All Products
Search
Document Center

Key Management Service:Sample code for signing and verification

Last Updated:Mar 31, 2026

Use the KMS instance SDK client to call the Sign and Verify APIs for asymmetric signing and signature verification. This topic provides a complete PHP example and a step-by-step walkthrough of each function.

Prerequisites

Before you begin, ensure that you have:

  • An initialized KMS instance SDK client. For setup details, see Initialize the client (PHP)

  • An asymmetric CMK created in KMS. Note the key ID

  • A ClientKey file and its password, obtained from KMS application management

  • The VPC address (endpoint) of your KMS instance

How it works

The sign-and-verify flow has three steps:

  1. Build a SignRequest with your key ID, message, message type, and signing algorithm, then call signWithOptions(). The response returns the signature and the algorithm used.

  2. Pass the original message and the sign response fields into a VerifyRequest, then call verifyWithOptions(). The response returns a boolean indicating whether the signature is valid.

  3. Inspect the boolean result to confirm success or handle failure.

All examples use the AlibabaCloud\Dkms\Gcs\Sdk package.

Complete example

The following self-contained script runs the full sign-and-verify cycle. Replace the placeholder values before running.

<?php

if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}

use AlibabaCloud\Dkms\Gcs\OpenApi\Util\Models\RuntimeOptions;
use AlibabaCloud\Dkms\Gcs\Sdk\Client as AlibabaCloudDkmsGcsSdkClient;
use AlibabaCloud\Dkms\Gcs\OpenApi\Models\Config as AlibabaCloudDkmsGcsOpenApiConfig;
use AlibabaCloud\Dkms\Gcs\Sdk\Models\SignRequest;
use AlibabaCloud\Dkms\Gcs\Sdk\Models\VerifyRequest;
use AlibabaCloud\Tea\Utils\Utils as AlibabaCloudTeaUtils;

// Alternatively, specify the path to the ClientKey file obtained from KMS application management.
// $clientKeyFile = '<CLIENT_KEY_FILE_PATH>';

// ClientKey content from KMS application management.
$clientKeyContent = '<CLIENT_KEY_CONTENT>';

// Password set when creating the ClientKey. Retrieved from an environment variable
// to avoid embedding credentials in source code.
$password = getenv('<CLIENT_KEY_PASSWORD>');

// VPC address of your KMS instance.
// Format: <KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com
$endpoint = '<DKMS_INSTANCE_SERVICE_ADDRESS>';

// ID of the asymmetric CMK to use for signing.
$keyId = '<ASYMMETRIC_CMK_ID>';

// Signing algorithm. Must match the key type.
// Supported values depend on the key spec (for example, RSA_PKCS1_SHA_256 for RSA keys).
$algorithm = '<SIGN_ALGORITHM>';

// Data to sign.
$message = '<MESSAGE_DATA>';

// Message type:
//   RAW     - pass the raw message; KMS computes the digest internally.
//   DIGEST  - pass a pre-computed message digest (hash) to skip rehashing.
$messageType = 'RAW';

$client = getDkmsGcsSdkClient();
if (is_null($client)) exit(1);

signVerifySample();

/**
 * Runs a complete sign-and-verify cycle.
 */
function signVerifySample(): void
{
    global $client, $keyId, $message, $messageType, $algorithm;

    $signatureCtx = signSample($client, $keyId, $message, $messageType, $algorithm);
    if ($signatureCtx !== null) {
        $verified = verifySample($client, $message, $signatureCtx);
        if (!$verified) {
            echo 'verify failed' . PHP_EOL;
        } else {
            echo 'signVerifySample success' . PHP_EOL;
        }
    }
}

/**
 * Signs a message using the Sign API.
 *
 * @param AlibabaCloudDkmsGcsSdkClient $client
 * @param string $keyId    ID of the asymmetric CMK.
 * @param string $message  Data to sign.
 * @param string $messageType  RAW or DIGEST.
 * @param string $algorithm    Signing algorithm.
 * @return SignatureContext|null  Returns null if signing fails.
 */
function signSample($client, $keyId, $message, $messageType, $algorithm): ?SignatureContext
{
    $signRequest = new SignRequest();
    $signRequest->keyId = $keyId;
    $signRequest->algorithm = $algorithm;
    $signRequest->message = AlibabaCloudTeaUtils::toBytes($message);
    $signRequest->messageType = $messageType;

    $runtimeOptions = new RuntimeOptions();
    // Uncomment to skip SSL certificate verification (not recommended for production).
    // $runtimeOptions->ignoreSSL = true;

    try {
        $signResponse = $client->signWithOptions($signRequest, $runtimeOptions);
        var_dump($signResponse->toMap());
        return new SignatureContext([
            'keyId'       => $signResponse->keyId,
            'signature'   => $signResponse->signature,
            'messageType' => $signResponse->messageType,
            'algorithm'   => $signResponse->algorithm,
        ]);
    } catch (Exception $error) {
        if ($error instanceof \AlibabaCloud\Tea\Exception\TeaError) {
            var_dump($error->getErrorInfo());
        }
        var_dump($error->getMessage());
        var_dump($error->getTraceAsString());
    }
    return null;
}

/**
 * Verifies a signature using the Verify API.
 *
 * @param AlibabaCloudDkmsGcsSdkClient $client
 * @param string $message           Original message (must match what was signed).
 * @param SignatureContext $ctx      Context returned by signSample().
 * @return bool  true if the signature is valid, false otherwise.
 */
function verifySample($client, $message, $ctx): bool
{
    $verifyRequest = new VerifyRequest();
    $verifyRequest->keyId      = $ctx->keyId;
    $verifyRequest->signature  = $ctx->signature;
    $verifyRequest->message    = AlibabaCloudTeaUtils::toBytes($message);
    $verifyRequest->messageType = $ctx->messageType;
    $verifyRequest->algorithm  = $ctx->algorithm;

    $runtimeOptions = new RuntimeOptions();
    // Uncomment to skip SSL certificate verification (not recommended for production).
    // $runtimeOptions->ignoreSSL = true;

    try {
        $verifyResponse = $client->verifyWithOptions($verifyRequest, $runtimeOptions);
        var_dump($verifyResponse->toMap());
        return (bool) $verifyResponse->value;
    } catch (Exception $error) {
        if ($error instanceof \AlibabaCloud\Tea\Exception\TeaError) {
            var_dump($error->getErrorInfo());
        }
        var_dump($error->getMessage());
        var_dump($error->getTraceAsString());
    }
    return false;
}

/**
 * Builds the KMS instance SDK client.
 *
 * @return AlibabaCloudDkmsGcsSdkClient
 */
function getDkmsGcsSdkClient(): AlibabaCloudDkmsGcsSdkClient
{
    global $clientKeyContent, $password, $endpoint;

    $config = new AlibabaCloudDkmsGcsOpenApiConfig();
    // KMS instance service requires HTTPS.
    $config->protocol = 'https';
    $config->clientKeyContent = $clientKeyContent;
    $config->password = $password;
    $config->endpoint = $endpoint;
    // Path to the CA certificate of your KMS instance.
    $config->caFilePath = 'path/to/caCert.pem';

    return new AlibabaCloudDkmsGcsSdkClient($config);
}

/**
 * Holds the output fields from a Sign API call.
 * Pass this object directly to verifySample() to ensure the key ID,
 * algorithm, and message type are consistent between signing and verification.
 */
class SignatureContext
{
    public function __construct($config = [])
    {
        foreach ($config as $k => $v) {
            $this->{$k} = $v;
        }
    }

    /** @var string */
    public $keyId;

    /** @var int[] Raw signature bytes. */
    public $signature;

    /** @var string RAW or DIGEST. */
    public $messageType;

    /**
     * @var string Signing algorithm. If not set, the key's default algorithm is used.
     */
    public $algorithm;
}

Placeholder reference

PlaceholderDescriptionExample
<CLIENT_KEY_CONTENT>Content of the ClientKey file from KMS application management{"KeyId":"...","PrivateKeyData":"..."}
<CLIENT_KEY_PASSWORD>Environment variable name that holds the ClientKey passwordKMS_CLIENT_KEY_PASSWORD
<DKMS_INSTANCE_SERVICE_ADDRESS>VPC endpoint of your KMS instancekst-hzz123.cryptoservice.kms.aliyuncs.com
<ASYMMETRIC_CMK_ID>ID of the asymmetric CMK in KMSkey-hzz456abc
<SIGN_ALGORITHM>Signing algorithm matching the key specRSA_PKCS1_SHA_256
<MESSAGE_DATA>Data to signhello world

Step-by-step walkthrough

The following sections explain each of the three functions in the complete example above.

Initialize the client

See Initialize the client (PHP) for the full getDkmsGcsSdkClient() implementation. The key configuration fields are:

FieldDescription
protocolAlways https. The KMS instance service only accepts HTTPS connections.
clientKeyContentClientKey file content from KMS application management.
passwordPassword set when creating the ClientKey.
endpointVPC address in the format <KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com.
caFilePathLocal path to the CA certificate of your KMS instance.

Call the Sign API

Build a SignRequest, call signWithOptions(), and store the response fields in a SignatureContext. The function returns null if signing fails.

Request fields:

FieldDescription
keyIdID of the asymmetric CMK.
algorithmSigning algorithm. Must match the key spec. For example, RSA_PKCS1_SHA_256 for RSA keys.
messageData to sign, as a byte array.
messageTypeRAW to pass raw data (KMS computes the digest); DIGEST to pass a pre-computed digest and skip rehashing.

Call the Verify API

Build a VerifyRequest using the fields from SignatureContext, then call verifyWithOptions(). The function returns true if the signature is valid.

Note: Pass the same message value used during signing. Passing a different message causes verification to fail.

Request fields:

FieldDescription
keyIdID of the asymmetric CMK (from SignatureContext).
signatureRaw signature bytes returned by the Sign API (from SignatureContext).
messageOriginal message — must match what was passed to signSample().
messageTypeMust match the value used during signing (from SignatureContext).
algorithmMust match the value used during signing (from SignatureContext).

What's next