Yandex Cloud
Search
Discuss with expertTry it for free
  • Customer Stories
  • Documentation
  • Blog
  • All Services
    • Cloud Interconnect
    • Cloud Backup
    • Cloud Registry
    • Yandex AI Studio
    • Compute Cloud
    • Object Storage
    • Managed Service for Kubernetes®
    • Yandex BareMetal
    • Smart Web Security
    • Security Deck
    • Managed Service for PostgreSQL
    • Managed Service for ClickHouse®
    • Monium
    • Cloud CDN
    • Network Load Balancer
    • Virtual Private Cloud
    • Cloud DNS
    • Application Load Balancer
    • Yandex Cloud Video
    • Stackland
    • Yandex Cloud Router
    • Yandex Managed Service for Trino
    • Managed Service for MySQL®
    • Managed Service for Valkey™
    • Managed Service for Apache Spark™
    • Yandex StoreDoc
    • Managed Service for OpenSearch
    • Managed Service for Apache Kafka®
    • Data Transfer
    • Yandex MPP Analytics Engine for PostgreSQL
    • Yandex Managed Service for Apache Airflow®
    • Data Processing
    • Yandex MetaData Hub
    • Managed Service for YDB
    • Managed Service for Sharded PostgreSQL
    • Managed Service for YTsaurus
    • Yandex WebSQL
    • DataLens
    • Yandex Search API
    • SpeechSense
    • SpeechKit
    • DataSphere
    • Vision OCR
    • Translate
    • Yandex Identity Hub
    • Key Management Service
    • Certificate Manager
    • Yandex Lockbox
    • Audit Trails
    • SmartCaptcha
    • Cloud Desktop
    • Yandex SIEM
    • SourceCraft Code Assistant
    • Container Registry
    • Managed Service for GitLab
    • Managed Service for Prometheus®
    • Cloud Functions
    • API Gateway
    • Yandex Cloud Postbox
    • Message Queue
    • Serverless Integrations
    • IoT Core
    • Data Streams
    • Serverless Containers
    • Cloud Notification Service
    • Yandex Query
    • Identity and Access Management
    • Yandex Cloud Console
    • Resource Manager
    • Yandex Cloud Billing
    • Yandex Cloud Quota Manager
    • Cloud Apps
  • System Status
  • Marketplace
    • Featured
    • Infrastructure & Network
    • Data Platform
    • AI for business
    • Security
    • DevOps tools
    • Serverless
    • Monitoring & Resources
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Start testing with double trial credits
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Center for Technologies and Society
    • Yandex Cloud Partner program
    • Price calculator
    • Pricing plans
  • Customer Stories
  • Documentation
  • Blog
© 2026 Direct Cursus Technology L.L.C.
Yandex Key Management Service
  • Getting started
    • All guides
      • Digital signature key pair
      • Access permissions for a digital signature key pair
      • Digital signature and its verification
      • Digital signature of files and artifacts using Cosign
    • Viewing operations on service resources
  • Access management
  • Pricing policy
  • Terraform reference
  • Monitoring metrics
  • Audit Trails events
  • FAQ

In this article:

  • Getting started
  • Create a digital signature
  • Private key-based message signature
  • Hash-based file signature
  • Verify the digital signature
  • ECDSA signature
  • RSA signature
  1. Step-by-step guides
  2. Digital signature
  3. Digital signature and its verification

Digital signature and its hash-based verification

Written by
Yandex Cloud
Updated at September 17, 2026
View in Markdown
  • Getting started
  • Create a digital signature
    • Private key-based message signature
  • Hash-based file signature
  • Verify the digital signature
    • ECDSA signature
    • RSA signature

In Key Management Service, you can create a digital signature that can be used to verify data authenticity and integrity, as well as to protect the signed data from modification.

Getting startedGetting started

This guide uses OpenSSL for digital signature verification. If you do not have OpenSSL yet, install it.

Linux
Windows

Run this command:

sudo apt-get install openssl

Use the Chocolatey package manager. Run the following command as an admin in the PowerShell terminal:

choco install openssl

Create a digital signatureCreate a digital signature

Depending on the size of the message or file to sign, KMS allows creating a private key-based or hash-based message signature.

Private key-based message signaturePrivate key-based message signature

Note

Private key-based signature is used for messages of up to 32 KB.

  1. If you do not have a digital signature key pair, create one.

  2. Get a signature public key and save it:

    Management console
    CLI
    1. In the management console, select the folder containing the digital signature key pair.
    2. Navigate to Key Management Service.
    3. In the left-hand panel, select Asymmetric keys.
    4. Navigate to the Signature tab.
    5. In the key pair row, click and select Public key.
    6. In the window that opens, click Download to download the digital signature public key.

    If you do not have the Yandex Cloud CLI yet, install and initialize it.

    The folder used by default is the one specified when creating the CLI profile. To change the default folder, use the yc config set folder-id <folder_ID> command. You can also specify a different folder for any command using --folder-name or --folder-id.

    If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

    1. View the description of the CLI command for getting a signature public key:

      yc kms asymmetric-signature-crypto get-public-key --help
      
    2. Get the ID of the folder containing the digital signature key pair.

    3. Get the ID of the required digital signature key pair by specifying the folder ID:

      yc kms asymmetric-signature-key list \
        --folder-id <folder_ID>
      

      Result:

      +----------------------+----------------------+---------------------------+---------------------+--------+
      |          ID          |         NAME         |    SIGNATURE ALGORITHM    |     CREATED AT      | STATUS |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      | abj9g2dil5sj******** | sample-signature-key | RSA_2048_SIGN_PSS_SHA_512 | 2023-08-16 09:06:57 | ACTIVE |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      
    4. Get a digital signature public key by specifying the previously obtained key pair ID:

      yc kms asymmetric-signature-crypto get-public-key \
        --id <key_pair_ID>
      

      Result:

      key_id: abj9g2dil5sj********
      public_key: |
      -----BEGIN PUBLIC KEY-----
      MIIB...
      ...QAB
      -----END PUBLIC KEY-----
      

      Save the obtained key to a file, such as public.key. Make sure that lines in the file do not start with spaces.

  3. Create a file with a base64-encoded message:

    1. Create a text file, e.g., message.txt:

      cat > message.txt
      My sample message.
      It will be used to verify ECDSA signature.
      

      The message size must not exceed 32 KB.

    2. Change the message encoding to base64 by specifying the path to the created base64-encoded message file:

      base64 message.txt > <base64_message_file>
      
  4. Create a message signature:

    CLI
    1. View the description of the CLI command for getting a digital signature:

      yc kms asymmetric-signature-crypto sign --help
      
    2. Get a digital signature for the message:

      yc kms asymmetric-signature-crypto sign \
        --id <key_pair_ID> \
        --signature-output-file <signature_file_path> \
        --message-file <message_file_path> \
        --inform base64 \
        --outform base64
      

      Where:

      • --id: ID of the digital signature key pair.
      • --signature-output-file: Path to the file to save the digital signature to.
      • --message-file: Path to the previously created file with the base64-encoded message.
      • --inform: Message file format. The possible values are raw (default), base64, and hex.
      • --outform: Signature file format. Possible values: raw (default), base64, and hex.

      Result:

      key_id: abjcg4mhmdfe********
      signature: MAa7C...imw==
      
    3. Change the digital signature format to DER, which is required for OpenSSL:

      echo -n "$(< <signature_file_path>)" | base64 -d > <signature_file>
      

      Where:

      • <signature_file_path>: Path to the signature file you got in the previous step.
      • <signature_file>: Path to the new signature file in DER format.

    The signature file in DER format can be used to verify the signature using OpenSSL.

Hash-based file signatureHash-based file signature

Note

Hash-based signature is used for messages or files over 32 KB.

  1. If you do not have a digital signature key pair, create one.

  2. Get a digital signature public key and save it:

    Management console
    CLI
    1. In the management console, select the folder containing the digital signature key pair.
    2. Navigate to Key Management Service.
    3. In the left-hand panel, select  Asymmetric keys.
    4. Navigate to the Signature tab.
    5. In the key pair row, click and select Public key.
    6. In the window that opens, click Download to download the signature public key.

    If you do not have the Yandex Cloud CLI yet, install and initialize it.

    The folder used by default is the one specified when creating the CLI profile. To change the default folder, use the yc config set folder-id <folder_ID> command. You can also specify a different folder for any command using --folder-name or --folder-id.

    If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

    1. View the description of the CLI command for getting a signature public key:

      yc kms asymmetric-signature-crypto get-public-key --help
      
    2. Get the ID of the folder containing the digital signature key pair.

    3. Get the ID of the required digital signature key pair by specifying the folder ID:

      yc kms asymmetric-signature-key list \
        --folder-id <folder_ID>
      

      Result:

      +----------------------+----------------------+---------------------------+---------------------+--------+
      |          ID          |         NAME         |    SIGNATURE ALGORITHM    |     CREATED AT      | STATUS |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      | abj9g2dil5sj******** | sample-signature-key | RSA_2048_SIGN_PSS_SHA_512 | 2023-08-16 09:06:57 | ACTIVE |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      
    4. Get a digital signature public key by specifying the previously obtained key pair ID:

      yc kms asymmetric-signature-crypto get-public-key \
        --id <key_pair_ID>
      

      Result:

      key_id: abj9g2dil5sj********
      public_key: |
      -----BEGIN PUBLIC KEY-----
      MIIB...
      ...QAB
      -----END PUBLIC KEY-----
      

      Save the obtained key to a file, such as public.key. Make sure that lines in the file do not start with spaces.

  3. Get the file hash:

    Bash
    PowerShell

    Run this command:

    echo -n \
      $(<hashing_algorithm> <source_file_path> | cut -d " " -f 1) > \
      <hash_file_path>
    

    Where:

    • <hashing_algorithm>: Hashing algorithm used to create the digital signature key pair. The hashing algorithm is specified above in the SIGNATURE ALGORITHM field of the results of getting the list of key pairs. The possible values are as follows:

      • sha256sum: For SHA-256 algorithms.
      • sha384sum: For SHA-384 algorithms.
      • sha512sum: For SHA-512 algorithms.
    • <path_to_source_file>: Path to the file to hash.

    • <path_to_hash_file>: Path to the file to save the hash to.

    Run this command:

    (Get-FileHash -Path <source_file_path> -Algorithm <hashing_algorithm>).Hash.ToLower() | `
      Out-File -FilePath <hash_file_path> `
      -encoding ASCII `
      -NoNewline
    

    Where:

    • <hashing_algorithm>: Hashing algorithm used to create the signature key pair. The hashing algorithm is specified above in the SIGNATURE ALGORITHM field of the results of getting the list of key pairs. The possible values are as follows:

      • SHA256: For SHA-256 algorithms.
      • SHA384: For SHA-384 algorithms.
      • SHA512: For SHA-512 algorithms.
    • <path_to_source_file>: Path to the file to hash.

    • <path_to_hash_file>: Path to the file to save the hash to.

    This will create a text file containing the hash of the source file.

  4. Create a hash-based file signature:

    CLI
    1. View the description of the CLI command for getting a hash-based digital signature:

      yc kms asymmetric-signature-crypto sign-hash --help
      
    2. Get the ID of the folder containing the digital signature key pair.

    3. Get the ID of the required digital signature key pair by specifying the folder ID:

      yc kms asymmetric-signature-key list \
        --folder-id <folder_ID>
      

      Result:

      +----------------------+----------------------+---------------------------+---------------------+--------+
      |          ID          |         NAME         |    SIGNATURE ALGORITHM    |     CREATED AT      | STATUS |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      | abj9g2dil5sj******** | sample-signature-key | RSA_2048_SIGN_PSS_SHA_512 | 2023-08-16 09:06:57 | ACTIVE |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      
    4. Get a hash-based digital signature:

      yc kms asymmetric-signature-crypto sign-hash \
        --id <key_pair_ID> \
        --signature-output-file <signature_file_path> \
        --message-hash-file <hash_file_path> \
        --inform hex
      

      Where:

      • --id: ID of the digital signature key pair.
      • --signature-output-file: Path to the file to save the digital signature to.
      • --message-hash-file: Path to the previously created hash file.
      • --inform: Hash file format. Our example uses the common hex format that is supported by all platforms. The possible values are raw (default), base64, and hex.

      Result:

      signature: W7V8A...22g==
      

Verify the digital signatureVerify the digital signature

ECDSA signatureECDSA signature

Bash
Java
Go
Python

Verify the digital signature using OpenSSL:

openssl dgst \
  -<hashing_algorithm> \
  -verify <path_to_public_key_file> \
  -signature <signature_file_path> \
  <path_to_signed_file>

Where:

  • <hashing_algorithm>: Hashing algorithm used to create the signature key pair. The possible values are as follows:
    • sha256: For SHA-256 algorithms.
    • sha384: For SHA-384 algorithms.
    • sha512: For SHA-512 algorithms.
  • -verify: Path to the signature public key file.
  • -signature: Path to the digital signature file.
  • <path_to_signed_file>: Path to the file whose digital signature is being verified.

If the signature is valid, OpenSSL will return the Verified OK status.

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.StringReader;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class VerifyEcdsaSign {

    public static void main(String[] args) throws Exception {
        String publicKeyPem = 
        """
        -- -- - BEGIN PUBLIC KEY-- -- -
        <public_key_contents>
            -- -- - END PUBLIC KEY-- -- - 
        """;
        String signatureStr = "<signature>";
        byte[] signatureDer = Base64.getDecoder().decode(signatureStr);
        System.out.println(verifyEcdsaSignature(publicKeyPem, signatureDer, "<message>", "<algorithm_type>"));
    }

    public static boolean verifyEcdsaSignature(String publicKeyPem, byte[] signatureDer, String message, String hash_algorithm)
    throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
    SignatureException, IOException {

        // Public key and subscription decoding
        PemReader pemReader = new PemReader(new StringReader(publicKeyPem));
        PemObject pemObject = pemReader.readPemObject();
        byte[] publicKeyBytes = pemObject.getContent();

        // Creating a PublicKey object from the decoded public key
        KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
        EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

        // Creating a Signature object and initializing it with a public key
        Signature signature = Signature.getInstance(hash_algorithm + "withECDSA", new BouncyCastleProvider());
        signature.initVerify(publicKey);

        // Updating a Signature Object with Message Data
        byte[] messageBytes = message.getBytes();
        signature.update(messageBytes);

        // Signature verification using original message and decoded signature
        return signature.verify(signatureDer);
    }
}

Where:

  • <public_key_contents>: Contents of the signature public key.
  • <signature>: Contents of the digital signature in the base64 encoding.
  • <message>: String containing the source message signed with the digital signature, or hash of the file signed with the digital signature.
  • <algorithm_type>: Hash function used for the signature. The possible values are SHA256, SHA384, and SHA512.

The code verifies the ECDSA signature. It returns true if the signature is valid, and false if it is not.

import (
    "crypto/ecdsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/asn1"
    "encoding/base64"
    "encoding/pem"
    "fmt"
    "hash"
    "log"
    "math/big"
)

func runEcdsaSignTest() {
    publicKeyPem := `-----BEGIN PUBLIC KEY-----
    <public_key_contents>
    -----END PUBLIC KEY-----`
    signatureB64 := "<signature>"
    signatureDER, _ := base64.StdEncoding.DecodeString(signatureB64)
    message := "<message>"

        fmt.Println(verifyEcdsa(publicKeyPem, signatureDER, message, <algorithm_type>))
}

type ECDSASignature struct {
    R, S *big.Int
}

func verifyEcdsa(publicKeyPem string, signatureDER []byte, message string, hashFunc hash.Hash) bool {

    // Decode the public key
    block, _ := pem.Decode([]byte(publicKeyPem))
    if block == nil {
        log.Fatal("failed to decode PEM block containing public key")
    }

    // Parse the public key
    pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
	    log.Fatal(err)
    }

    publicKey, ok := pub.(*ecdsa.PublicKey)
    if !ok {
	    log.Fatal("not ECDSA public key")
    }

    // Parse the signature
    var signature ECDSASignature
    _, err = asn1.Unmarshal(signatureDER, &signature)
    if err != nil {
	    log.Fatal(err)
    }

    // Compute the hash of the message
    hashFunc.Write([]byte(message))
    hashed := hashFunc.Sum(nil)

    // Verify the signature
    return ecdsa.Verify(publicKey, hashed, signature.R, signature.S)
}

Where:

  • <public_key_contents>: Contents of the signature public key in the base64 encoding.
  • <signature>: Contents of the digital signature in the base64 encoding.
  • <message>: String containing the source message signed with the digital signature, or hash of the file signed with the digital signature.
  • <algorithm_type>: Hash function used for the signature. The possible values are sha256.New(), sha512.New384(), and sha512.New().

The code verifies the ECDSA signature. It returns true if the signature is valid, and false if it is not.

import base64
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend

# Define hash algorithms
def verify_ecdsa_signature(public_key_b64, signature_der, message, hash_algorithm):
    hash_algorithms = {
        'SHA256': hashes.SHA256,
        'SHA384': hashes.SHA384,
        'SHA512': hashes.SHA512
    }

    # Check if the provided hash algorithm is supported
    if hash_algorithm not in hash_algorithms:
        raise ValueError('Unsupported hash algorithm: ' + hash_algorithm)

    # Loading a PEM Encoded Public Key
    public_key = serialization.load_pem_public_key(
        public_key_b64.encode(),
        backend = default_backend()
    )

    # Create Signature object and initialize it with the public key
    signature = ec.ECDSA(hash_algorithms[hash_algorithm]())

    # Update the Signature object with the message data
    message_bytes = message.encode()

    # Verify the signature using the original message and the decoded signature
    try:
        public_key.verify(signature_der, message_bytes, signature)
        return True
    except InvalidSignature:
        return False

def test_verify_signature():
    public_key_b64 = """
    -----BEGIN PUBLIC KEY-----
    <public_key_contents>
    -----END PUBLIC KEY-----"""
    signature_b64 = "<signature>"
    signature_der = base64.b64decode(signature_b64)
    message = '<message>'
    print(verify_ecdsa_signature(public_key_b64, signature_der, message, "<algorithm_type>"))

Where:

  • <public_key_contents>: Contents of the signature public key.
  • <signature>: Contents of the digital signature in the base64 encoding.
  • <message>: String containing the source message signed with the digital signature, or hash of the file signed with the digital signature.
  • <algorithm_type>: Hash function used for the signature. The possible values are SHA256, SHA384, and SHA512.

The code verifies the ECDSA signature. It returns true if the signature is valid, and false if it is not.

RSA signatureRSA signature

Bash
Java
Go
Python

Verify the digital signature using OpenSSL:

openssl dgst \
  -<hashing_algorithm> \
  -sigopt rsa_padding_mode:pss \
  -sigopt rsa_pss_saltlen:-1 \
  -verify <path_to_public_key_file> \
  -signature <signature_file_path> \
  <path_to_signed_file>

Where:

  • <hashing_algorithm>: Hashing algorithm used to create the signature key pair. The possible values are as follows:
    • sha256: For SHA-256 algorithms.
    • sha384: For SHA-384 algorithms.
    • sha512: For SHA-512 algorithms.
  • -verify: Path to the signature public key file.
  • -signature: Path to the digital signature file.
  • <path_to_signed_file>: Path to the file whose digital signature is being verified.

If the signature is valid, OpenSSL will return the Verified OK status.

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.StringReader;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

public class VerifyRsaSign {

    public static void main(String[] args) throws Exception {
        String publicKeyPem = """
        -----BEGIN PUBLIC KEY-----
        <public_key_contents>
        -----END PUBLIC KEY-----""";
        String signatureStr = "<signature>";
        byte[] signatureBytes = Base64.getDecoder().decode(signatureStr);
        String message = "<message>";
        System.out.println(verifyRsaSignature(publicKeyPem, signatureBytes, message, "<algorithm_type>"));
    }

    private static boolean verifyRsaSignature(String publicKeyPem, byte[] signatureBytes, String message, String hashAlgorithm)
    throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
    SignatureException, InvalidAlgorithmParameterException, IOException {

        // Get the public key
        PemReader pemReader = new PemReader(new StringReader(publicKeyPem));
        PemObject pemObject = pemReader.readPemObject();
        byte[] publicKeyBytes = pemObject.getContent();

        // Create a PublicKey object using the decoded public key
        KeyFactory keyFactory = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
        EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);

        MessageDigest messageDigest = MessageDigest.getInstance(hashAlgorithm);
        int saltLength = messageDigest.getDigestLength();

        // Initialize the PSS signer
        PSSParameterSpec pssSpec = new PSSParameterSpec(hashAlgorithm, "MGF1", new MGF1ParameterSpec(hashAlgorithm), saltLength, 1);
        Signature signer = Signature.getInstance("RSASSA-PSS");
        signer.setParameter(pssSpec);
        signer.initVerify(pubKey);

        // Update the signature with the hash of the message
        byte[] messageBytes = message.getBytes();
        signer.update(messageBytes);

        // Verify the signature
        return signer.verify(signatureBytes);
    }
}

Where:

  • <public_key_contents>: Contents of the signature public key.
  • <signature>: Contents of the digital signature in the base64 encoding.
  • <message>: String containing the source message signed with the digital signature, or hash of the file signed with the digital signature.
  • <algorithm_type>: Hash function used for the signature. The possible values are SHA256, SHA384, and SHA512.

The code verifies the RSA digital signature. It returns true if the signature is valid, and false if it is not.

import (
    "crypto"
    "crypto/rsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
    "log"
)

func runRsaSignTest() {
    publicKeyB64 := "<public_key_contents>"
    signatureB64 := "<signature>"
    signatureBytes, _ := base64.StdEncoding.DecodeString(signatureB64)
    message := "<message>"

        fmt.Println(verifyRsa(publicKeyB64, signatureBytes, message, <algorithm_type>))
}

func verifyRsa(publicKeyPem string, signatureBytes []byte, message string, hash crypto.Hash) bool {

    // Decode the public key
    block, _ := pem.Decode([]byte(publicKeyPem))
    if block == nil {
        log.Fatal("failed to decode PEM block containing public key")
    }

    // Parse the public key
    pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
	    log.Fatal(err)
    }

    publicKey, ok := pub.(*rsa.PublicKey)
    if !ok {
	    log.Fatal("not RSA public key")
    }

    // Calculate the hash of the message
    hasher := hash.New()
    hasher.Write([]byte(message))
    hashed := hasher.Sum(nil)

    // Set the PSS options: salt length auto, and the hash function
    pssOptions := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthAuto, Hash: hash}

    // Verify the signature
    err = rsa.VerifyPSS(publicKey, hash, hashed, signatureBytes, pssOptions)
    if err != nil {
	    fmt.Println("Verification failed:", err)
	    return false
    } else {
	    return true
    }
}

Where:

  • <public_key_contents>: Contents of the signature public key in the base64 encoding.
  • <signature>: Contents of the digital signature in the base64 encoding.
  • <message>: String containing the source message signed with the digital signature, or hash of the file signed with the digital signature.
  • <algorithm_type>: Hash function used for the signature. The possible values are crypto.SHA256, crypto.SHA384, and crypto.SHA512.

The code verifies the RSA digital signature. It returns true if the signature is valid, and false if it is not.

import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend

# Define hash algorithms and corresponding salt lengths
def verify_rsa_signature(public_key_b64, signature_bytes, message, hash_algorithm):
    hash_algorithms = {
        'SHA256': hashes.SHA256,
        'SHA384': hashes.SHA384,
        'SHA512': hashes.SHA512
    }

    # Check if the provided hash algorithm is supported
    if hash_algorithm not in hash_algorithms:
        raise ValueError('Unsupported hash algorithm: ' + hash_algorithm)

    # Loading a PEM Encoded Public Key
    public_key = serialization.load_pem_public_key(
        public_key_b64.encode(),
        backend=default_backend()
    )

    # Update the Signature object with the message data
    message_bytes = message.encode()

    # Automatically calculate salt length based on hash digest size
    salt_length = hash_algorithms[hash_algorithm]().digest_size

    # Verify the signature using the original message and the decoded signature
    try:
        public_key.verify(
            signature_bytes,
            message_bytes,
            padding.PSS(
                mgf = padding.MGF1(hash_algorithms[hash_algorithm]()),
                salt_length = salt_length
            ),
            hash_algorithms[hash_algorithm]()
        )
        return True
    except InvalidSignature:
        return False

def test_verify_signature():
    public_key_b64 = """
    -----BEGIN PUBLIC KEY-----
    <public_key_contents>
    -----END PUBLIC KEY-----"""
    signature_b64 = '<signature>'
    signature_bytes = base64.b64decode(signature_b64)
    message = '<message>'
    print(verify_rsa_signature(public_key_b64, signature_bytes, message, '<algorithm_type>'))

Where:

  • <public_key_contents>: Contents of the signature public key in the base64 encoding.
  • <signature>: Contents of the digital signature in the base64 encoding.
  • <message>: String containing the source message signed with the digital signature, or hash of the file signed with the digital signature.
  • <algorithm_type>: Hash function used for the signature. The possible values are SHA256, SHA384, and SHA512.

The code verifies the RSA digital signature. It returns true if the signature is valid, and false if it is not.

Was the article helpful?

Previous
Access permissions for a digital signature key pair
Next
Digital signature of files and artifacts using Cosign
© 2026 Direct Cursus Technology L.L.C.