Creating and validating MAC digital signatures

This page shows you how to create and validate digital signaturesbased on MAC keys.

A single key, shared by both the producer and the verifier, is used to compute aMAC tag from the input data. The MAC tag serves as a digital signature. When theverifier receives the message and its associated MAC tag, they generate theirown tag from the message contents. The verifier can then compare the receivedtag with their generated tag to see whether they match. If the two tags match,the verifier knows that the message they received is the same as the messagesigned by the producer.

Before you begin

  • When creating MAC digital signatures, you must use a key that has thekey purpose ofMAC. When youcreate the key, useMAC.

  • Ensure that the file that you want to sign is within the file sizelimit.When you use aCloud HSM key, the maximum file size for which you can createa MAC signature is 16 KiB. For all other keys, the maximum file sizeis 64 KiB.

Required roles

To get the permissions that you need to create and verify signatures, ask your administrator to grant you the following IAM roles on the key:

For more information about granting roles, seeManage access to projects, folders, and organizations.

You might also be able to get the required permissions throughcustom roles or otherpredefined roles.

Note: If you're going to use a service account for signing or verification,grant the required role to the service account.

Creating a MAC signature

gcloud

To use Cloud KMS on the command line, firstInstall or upgrade to the latest version of Google Cloud CLI.

gcloud kms mac-sign \    --versionKEY_VERSION \    --keyKEY_NAME \    --keyringKEY_RING \    --locationLOCATION \    --input-fileINPUT_FILE_PATH \    --signature-fileSIGNED_FILE_PATH

Replace the following:

  • KEY_VERSION: the key version number.
  • KEY_NAME: the name of the key.
  • KEY_RING: the name of the key ring that contains the key.
  • LOCATION: the Cloud KMS location of the key ring.
  • INPUT_FILE_PATH: The local path to the file you want to sign.
  • SIGNED_FILE_PATH: The local path where you want to save thegenerated signature.

For information on all flags and possible values, run the command with the--help flag.

C#

To run this code, firstset up a C# development environment andinstall the Cloud KMS C# SDK.

usingGoogle.Cloud.Kms.V1;usingGoogle.Protobuf;publicclassSignMacSample{publicbyte[]SignMac(stringprojectId="my-project",stringlocationId="us-east1",stringkeyRingId="my-key-ring",stringkeyId="my-key",stringkeyVersionId="123",stringdata="Sample data"){// Create the client.KeyManagementServiceClientclient=KeyManagementServiceClient.Create();// Build the key version name.CryptoKeyVersionNamekeyVersionName=newCryptoKeyVersionName(projectId,locationId,keyRingId,keyId,keyVersionId);// Convert the data into a ByteString.ByteStringdataByteString=ByteString.CopyFromUtf8(data);// Call the API.MacSignResponseresult=client.MacSign(keyVersionName,dataByteString);// The data comes back as raw bytes, which may include non-printable// characters. To print the result, you could encode it as base64.// string encodedSignature = result.Mac.ToBase64();// Get the signature.byte[]signature=result.Mac.ToByteArray();// Return the result.returnsignature;}}

Go

To run this code, firstset up a Go development environment andinstall the Cloud KMS Go SDK.

import("context""encoding/base64""fmt""io"kms"cloud.google.com/go/kms/apiv1""cloud.google.com/go/kms/apiv1/kmspb")// signMac will sign a plaintext message using the HMAC algorithm.funcsignMac(wio.Writer,namestring,datastring)error{// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"// data := "my data to sign"// Create the client.ctx:=context.Background()client,err:=kms.NewKeyManagementClient(ctx)iferr!=nil{returnfmt.Errorf("failed to create kms client: %w",err)}deferclient.Close()// Build the request.req:=&kmspb.MacSignRequest{Name:name,Data:[]byte(data),}// Generate HMAC of data.result,err:=client.MacSign(ctx,req)iferr!=nil{returnfmt.Errorf("failed to hmac sign: %w",err)}// The data comes back as raw bytes, which may include non-printable// characters. This base64-encodes the result so it can be printed below.encodedSignature:=base64.StdEncoding.EncodeToString(result.Mac)fmt.Fprintf(w,"Signature: %s",encodedSignature)returnnil}

Java

To run this code, firstset up a Java development environment andinstall the Cloud KMS Java SDK.

importcom.google.cloud.kms.v1.CryptoKeyVersionName;importcom.google.cloud.kms.v1.KeyManagementServiceClient;importcom.google.cloud.kms.v1.MacSignResponse;importcom.google.protobuf.ByteString;importjava.io.IOException;importjava.util.Base64;publicclassSignMac{publicvoidsignMac()throwsIOException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringlocationId="us-east1";StringkeyRingId="my-key-ring";StringkeyId="my-key";StringkeyVersionId="123";Stringdata="Data to sign";signMac(projectId,locationId,keyRingId,keyId,keyVersionId,data);}// Sign data with a given mac key.publicvoidsignMac(StringprojectId,StringlocationId,StringkeyRingId,StringkeyId,StringkeyVersionId,Stringdata)throwsIOException{// Initialize client that will be used to send requests. This client only// needs to be created once, and can be reused for multiple requests. After// completing all of your requests, call the "close" method on the client to// safely clean up any remaining background resources.try(KeyManagementServiceClientclient=KeyManagementServiceClient.create()){// Build the key version name from the project, location, key ring, key,// and key version.CryptoKeyVersionNamekeyVersionName=CryptoKeyVersionName.of(projectId,locationId,keyRingId,keyId,keyVersionId);// Generate an HMAC of the data.MacSignResponseresponse=client.macSign(keyVersionName,ByteString.copyFromUtf8(data));// The data comes back as raw bytes, which may include non-printable// characters. This base64-encodes the result so it can be printed below.StringencodedSignature=Base64.getEncoder().encodeToString(response.getMac().toByteArray());System.out.printf("Signature: %s%n",encodedSignature);}}}

Node.js

To run this code, firstset up a Node.js development environment andinstall the Cloud KMS Node.js SDK.

//// TODO(developer): Uncomment these variables before running the sample.//// const projectId = 'your-project-id';// const locationId = 'us-east1';// const keyRingId = 'my-key-ring';// const keyId = 'my-key';// const versionId = '123';// const data = Buffer.from('...');// Imports the Cloud KMS libraryconst{KeyManagementServiceClient}=require('@google-cloud/kms');// Instantiates a clientconstclient=newKeyManagementServiceClient();// Build the version nameconstversionName=client.cryptoKeyVersionPath(projectId,locationId,keyRingId,keyId,versionId);asyncfunctionsignMac(){// Sign the data with Cloud KMSconst[signResponse]=awaitclient.macSign({name:versionName,data:data,});// Example of how to display signature. Because the signature is in a binary// format, you need to encode the output before printing it to a console or// displaying it on a screen.constencoded=signResponse.mac.toString('base64');console.log(`Signature:${encoded}`);returnsignResponse;}returnsignMac();

Python

To run this code, firstset up a Python development environment andinstall the Cloud KMS Python SDK.

fromgoogle.cloudimportkmsdefsign_mac(project_id:str,location_id:str,key_ring_id:str,key_id:str,version_id:str,data:str,)->kms.MacSignResponse:"""    Sign a message using the private key part of an asymmetric key.    Args:        project_id (string): Google Cloud project ID (e.g. 'my-project').        location_id (string): Cloud KMS location (e.g. 'us-east1').        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').        key_id (string): ID of the key to use (e.g. 'my-key').        version_id (string): Version to use (e.g. '1').        data (string): Data to sign.    Returns:        MacSignResponse: Signature.    """# Import base64 for printing the ciphertext.importbase64# Create the client.client=kms.KeyManagementServiceClient()# Build the key version name.key_version_name=client.crypto_key_version_path(project_id,location_id,key_ring_id,key_id,version_id)# Convert the message to bytes.data_bytes=data.encode("utf-8")# Call the APIsign_response=client.mac_sign(request={"name":key_version_name,"data":data_bytes})print(f"Signature:{base64.b64encode(sign_response.mac)!r}")returnsign_response

Ruby

To run this code, firstset up a Ruby development environment andinstall the Cloud KMS Ruby SDK.

# TODO(developer): uncomment these values before running the sample.# project_id  = "my-project"# location_id = "us-east1"# key_ring_id = "my-key-ring"# key_id      = "my-key"# version_id  = "123"# data        = "my data"# Require the library.require"google/cloud/kms"# Require digest.require"digest"# Create the client.client=Google::Cloud::Kms.key_management_service# Build the key version name.key_version_name=client.crypto_key_version_pathproject:project_id,location:location_id,key_ring:key_ring_id,crypto_key:key_id,crypto_key_version:version_id# Call the API.sign_response=client.mac_signname:key_version_name,data:data# The data comes back as raw bytes, which may include non-printable# characters. This base64-encodes the result so it can be printed below.encoded_signature=Base64.strict_encode64sign_response.macputs"Signature:#{encoded_signature}"

API

These examples usecurl as an HTTP client to demonstrate using the API. For more information about access control, seeAccessing the Cloud KMS API.

Use theCryptoKeyVersions.macSignmethod to perform the signing. The response from this method contains thebase64-encoded signature.

Tip: You can base64-encode or decode datausing thebase64 command on Linux or macOS, or theBase64.exe command on Windows. Programming and scriptinglanguages typically include libraries for base64-encoding. For command-lineexamples, seeBase64 Encoding in theCloud Vision API documentation.

Verifying a MAC signature

gcloud

To use Cloud KMS on the command line, firstInstall or upgrade to the latest version of Google Cloud CLI.

gcloud kms mac-verify \    --versionKEY_VERSION \    --keyKEY_NAME \    --keyringKEY_RING \    --locationLOCATION \    --input-fileINPUT_FILE_PATH \    --signature-fileSIGNED_FILE_PATH
  • KEY_VERSION: the key version number.
  • KEY_NAME: the name of the key.
  • KEY_RING: the name of the key ring that contains the key.
  • LOCATION: the Cloud KMS location of the key ring.
  • INPUT_FILE_PATH: The local path to the file that was signed.
  • SIGNED_FILE_PATH: The local path to the signature file tobe verified.

For information on all flags and possible values, run the command with the--help flag.

C#

To run this code, firstset up a C# development environment andinstall the Cloud KMS C# SDK.

usingGoogle.Cloud.Kms.V1;usingGoogle.Protobuf;publicclassVerifyMacSample{publicboolVerifyMac(stringprojectId="my-project",stringlocationId="us-east1",stringkeyRingId="my-key-ring",stringkeyId="my-key",stringkeyVersionId="123",stringdata="my data",byte[]signature=null){// Build the key version name.CryptoKeyVersionNamekeyVersionName=newCryptoKeyVersionName(projectId,locationId,keyRingId,keyId,keyVersionId);// Create the client.KeyManagementServiceClientclient=KeyManagementServiceClient.Create();// Convert the data and signatures into ByteStrings.ByteStringdataByteString=ByteString.CopyFromUtf8(data);ByteStringsignatureByteString=ByteString.CopyFrom(signature);// Verify the signature.MacVerifyResponseresult=client.MacVerify(keyVersionName,dataByteString,signatureByteString);// Return the result.returnresult.Success;}}

Go

To run this code, firstset up a Go development environment andinstall the Cloud KMS Go SDK.

import("context""fmt""io"kms"cloud.google.com/go/kms/apiv1""cloud.google.com/go/kms/apiv1/kmspb")// verifyMac will verify a previous HMAC signature.funcverifyMac(wio.Writer,namestring,data,signature[]byte)error{// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"// data := "my previous data"// signature := []byte("...")  // Response from a sign request// Create the client.ctx:=context.Background()client,err:=kms.NewKeyManagementClient(ctx)iferr!=nil{returnfmt.Errorf("failed to create kms client: %w",err)}deferclient.Close()// Build the request.req:=&kmspb.MacVerifyRequest{Name:name,Data:data,Mac:signature,}// Verify the signature.result,err:=client.MacVerify(ctx,req)iferr!=nil{returnfmt.Errorf("failed to verify signature: %w",err)}fmt.Fprintf(w,"Verified: %t",result.Success)returnnil}

Java

To run this code, firstset up a Java development environment andinstall the Cloud KMS Java SDK.

importcom.google.cloud.kms.v1.CryptoKeyVersionName;importcom.google.cloud.kms.v1.KeyManagementServiceClient;importcom.google.cloud.kms.v1.MacVerifyResponse;importcom.google.protobuf.ByteString;importjava.io.IOException;publicclassVerifyMac{publicvoidverifyMac()throwsIOException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringlocationId="us-east1";StringkeyRingId="my-key-ring";StringkeyId="my-key";StringkeyVersionId="123";Stringdata="Data to sign";byte[]signature=null;verifyMac(projectId,locationId,keyRingId,keyId,keyVersionId,data,signature);}// Sign data with a given mac key.publicvoidverifyMac(StringprojectId,StringlocationId,StringkeyRingId,StringkeyId,StringkeyVersionId,Stringdata,byte[]signature)throwsIOException{// Initialize client that will be used to send requests. This client only// needs to be created once, and can be reused for multiple requests. After// completing all of your requests, call the "close" method on the client to// safely clean up any remaining background resources.try(KeyManagementServiceClientclient=KeyManagementServiceClient.create()){// Build the key version name from the project, location, key ring, key,// and key version.CryptoKeyVersionNamekeyVersionName=CryptoKeyVersionName.of(projectId,locationId,keyRingId,keyId,keyVersionId);// Verify the signatureMacVerifyResponseresponse=client.macVerify(keyVersionName,ByteString.copyFromUtf8(data),ByteString.copyFrom(signature));// The data comes back as raw bytes, which may include non-printable// characters. This base64-encodes the result so it can be printed below.System.out.printf("Success: %s%n",response.getSuccess());}}}

Node.js

To run this code, firstset up a Node.js development environment andinstall the Cloud KMS Node.js SDK.

//// TODO(developer): Uncomment these variables before running the sample.//// const projectId = 'your-project-id';// const locationId = 'us-east1';// const keyRingId = 'my-key-ring';// const keyId = 'my-key';// const versionId = '123';// const data = Buffer.from('...');// const signature = Buffer.from('...');// Imports the Cloud KMS libraryconst{KeyManagementServiceClient}=require('@google-cloud/kms');// Instantiates a clientconstclient=newKeyManagementServiceClient();// Build the version nameconstversionName=client.cryptoKeyVersionPath(projectId,locationId,keyRingId,keyId,versionId);asyncfunctionverifyMac(){// Verify the data with Cloud KMSconst[verifyResponse]=awaitclient.macVerify({name:versionName,data:data,mac:signature,});console.log(`Verified:${verifyResponse.success}`);returnverifyResponse;}returnverifyMac();

Python

To run this code, firstset up a Python development environment andinstall the Cloud KMS Python SDK.

fromgoogle.cloudimportkmsdefverify_mac(project_id:str,location_id:str,key_ring_id:str,key_id:str,version_id:str,data:str,signature:bytes,)->kms.MacVerifyResponse:"""    Verify the signature of data from an HMAC key.    Args:        project_id (string): Google Cloud project ID (e.g. 'my-project').        location_id (string): Cloud KMS location (e.g. 'us-east1').        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').        key_id (string): ID of the key to use (e.g. 'my-key').        version_id (string): Version to use (e.g. '1').        data (string): Data that was signed.        signature (bytes): Signature bytes.    Returns:        MacVerifyResponse: Success.    """# Create the client.client=kms.KeyManagementServiceClient()# Build the key version name.key_version_name=client.crypto_key_version_path(project_id,location_id,key_ring_id,key_id,version_id)# Convert the message to bytes.data_bytes=data.encode("utf-8")# Call the APIverify_response=client.mac_verify(request={"name":key_version_name,"data":data_bytes,"mac":signature})print(f"Verified:{verify_response.success}")returnverify_response

Ruby

To run this code, firstset up a Ruby development environment andinstall the Cloud KMS Ruby SDK.

# TODO(developer): uncomment these values before running the sample.# project_id  = "my-project"# location_id = "us-east1"# key_ring_id = "my-key-ring"# key_id      = "my-key"# version_id  = "123"# data        = "my data"# signature   = "..."# Require the library.require"google/cloud/kms"# Require digest.require"digest"# Create the client.client=Google::Cloud::Kms.key_management_service# Build the key version name.key_version_name=client.crypto_key_version_pathproject:project_id,location:location_id,key_ring:key_ring_id,crypto_key:key_id,crypto_key_version:version_id# Call the API.verify_response=client.mac_verifyname:key_version_name,data:data,mac:signatureputs"Verified:#{verify_response.success}"

API

These examples usecurl as an HTTP client to demonstrate using the API. For more information about access control, seeAccessing the Cloud KMS API.

Use theCryptoKeyVersions.macVerifymethod to perform the verification. The signature to be verified needs to bebase64-encoded. The response from this method contains a boolean indicatingwhether or not the signature was verified successfully.

Tip: You can base64-encode or decode datausing thebase64 command on Linux or macOS, or theBase64.exe command on Windows. Programming and scriptinglanguages typically include libraries for base64-encoding. For command-lineexamples, seeBase64 Encoding in theCloud Vision API documentation.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-17 UTC.