All Products
Search
Document Center

Key Management Service:Sample code for signing and verification

Last Updated:Mar 31, 2026

Use the KMS instance SDK Python client to sign data and verify digital signatures with an asymmetric key. This page provides a complete working example followed by a step-by-step breakdown.

All examples use sign_with_options and verify_with_options to submit requests through a configured client.

Prerequisites

Before you begin, ensure that you have:

  • Initialized the KMS instance SDK client. See Initialize the client

  • An asymmetric key ID (key_id) and a supported signing algorithm

Complete example

# -*- coding: utf-8 -*-
import os

from openapi.models import Config
from openapi_util.models import RuntimeOptions
from sdk.client import Client
from sdk.models import SignRequest, VerifyRequest

config = Config()
# KMS instance service only allows HTTPS access.
config.protocol = "https"
# Path to the Client Key file.
config.client_key_file = "<CLIENT_KEY_FILE>"
# Client Key decryption password, loaded from an environment variable.
config.password = os.getenv('CLIENT_KEY_PASSWORD')
# Endpoint format: <KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com
config.endpoint = "<ENDPOINT>"
client = Client(config)


class SignContext(object):
    """Stores sign response fields needed for subsequent verification."""

    def __init__(self, key_id, message_type, signature, algorithm):
        self.key_id = key_id
        self.message_type = message_type
        self.signature = signature
        # If algorithm is not set, the default value is used.
        self.algorithm = algorithm


def sign(key_id, message, message_type, algorithm):
    request = SignRequest()
    request.key_id = key_id
    request.message = message
    request.message_type = message_type
    request.algorithm = algorithm
    runtime_options = RuntimeOptions()
    # Uncomment the line below to skip server certificate verification.
    # runtime_options.ignore_ssl = True
    # Path to the instance CA certificate.
    runtime_options.verify = "<CA_CERTIFICATE_FILE_PATH>"
    resp = client.sign_with_options(request, runtime_options)
    print(resp)
    return SignContext(resp.key_id, resp.message_type, resp.signature, resp.algorithm)


def verify(context, message):
    request = VerifyRequest()
    request.key_id = context.key_id
    request.message_type = context.message_type
    request.signature = context.signature
    request.algorithm = context.algorithm
    request.message = message
    runtime_options = RuntimeOptions()
    # Uncomment the line below to skip server certificate verification.
    # runtime_options.ignore_ssl = True
    # Path to the instance CA certificate.
    runtime_options.verify = "<CA_CERTIFICATE_FILE_PATH>"
    resp = client.verify_with_options(request, runtime_options)
    print(resp)


key_id = "<KEY_ID>"
algorithm = "<ALGORITHM>"
message = "<MESSAGE>".encode("utf-8")
# RAW: pass the raw message. DIGEST: pass the digest of the message.
message_type = "RAW"
context = sign(key_id, message, message_type, algorithm)
verify(context, message)

Replace the following placeholders before running the code:

PlaceholderDescriptionExample
<CLIENT_KEY_FILE>Path to the Client Key file/path/to/clientKey.json
<ENDPOINT>KMS instance endpointkst-example.cryptoservice.kms.aliyuncs.com
<CA_CERTIFICATE_FILE_PATH>Path to the instance CA certificate/path/to/ca.pem
<KEY_ID>ID of the asymmetric keykey-12345abcde
<ALGORITHM>Signing algorithm supported by the keyRSA_PKCS1_SHA_256
<MESSAGE>Data to signhello

Step-by-step walkthrough

Initialize the client

See Initialize the client for full setup instructions. Set config.protocol to "https" — the KMS instance service only accepts HTTPS connections.

# -*- coding: utf-8 -*-
import os

from openapi.models import Config
from sdk.client import Client

config = Config()
config.protocol = "https"
config.client_key_file = "<CLIENT_KEY_FILE>"
config.password = os.getenv('CLIENT_KEY_PASSWORD')
# Format: <KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com
config.endpoint = "<ENDPOINT>"
client = Client(config)

Sign data with an asymmetric key

Call the Sign API to generate a digital signature.

Set message_type to "RAW" to sign the raw message, or "DIGEST" to sign a pre-computed message digest.

def sign(key_id, message, message_type, algorithm):
    request = SignRequest()
    request.key_id = key_id          # ID of the asymmetric key to use
    request.message = message        # Data to sign (bytes)
    request.message_type = message_type  # "RAW" or "DIGEST"
    request.algorithm = algorithm    # Signing algorithm the key supports
    runtime_options = RuntimeOptions()
    # runtime_options.ignore_ssl = True  # Uncomment to skip certificate verification
    runtime_options.verify = "<CA_CERTIFICATE_FILE_PATH>"
    resp = client.sign_with_options(request, runtime_options)
    print(resp)
    return SignContext(resp.key_id, resp.message_type, resp.signature, resp.algorithm)

The Sign response includes:

FieldDescription
resp.key_idID of the key that generated the signature
resp.signatureThe digital signature (bytes)
resp.algorithmThe signing algorithm used
resp.message_typeThe message type (RAW or DIGEST)

SignContext stores these fields so you can pass them directly to verify().

Verify a digital signature

Call the Verify API to validate a signature against the original message.

def verify(context, message):
    request = VerifyRequest()
    request.key_id = context.key_id          # Must match the key used to sign
    request.message_type = context.message_type
    request.signature = context.signature    # Signature from the Sign response
    request.algorithm = context.algorithm    # Must match the algorithm used to sign
    request.message = message                # Original data (same as what was signed)
    runtime_options = RuntimeOptions()
    # runtime_options.ignore_ssl = True  # Uncomment to skip certificate verification
    runtime_options.verify = "<CA_CERTIFICATE_FILE_PATH>"
    resp = client.verify_with_options(request, runtime_options)
    print(resp)

What's next