KMS API를 사용하여 입력 메시지의 SHA-256 해시의 비대칭 서명을 검색합니다.
더 살펴보기
이 코드 샘플이 포함된 자세한 문서는 다음을 참조하세요.
코드 샘플
C#
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
using Google.Cloud.Kms.V1;
using Google.Protobuf;
using System.Security.Cryptography;
using System.Text;
public class SignAsymmetricSample
{
public byte[] SignAsymmetric(
string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring", string keyId = "my-key", string keyVersionId = "123",
string message = "Sample message")
{
// Create the client.
KeyManagementServiceClient client = KeyManagementServiceClient.Create();
// Build the key version name.
CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(projectId, locationId, keyRingId, keyId, keyVersionId);
// Convert the message into bytes. Cryptographic plaintexts and
// ciphertexts are always byte arrays.
byte[] plaintext = Encoding.UTF8.GetBytes(message);
// Calculate the digest.
SHA256 sha256 = SHA256.Create();
byte[] hash = sha256.ComputeHash(plaintext);
// Build the digest.
//
// Note: Key algorithms will require a varying hash function. For
// example, EC_SIGN_P384_SHA384 requires SHA-384.
Digest digest = new Digest
{
Sha256 = ByteString.CopyFrom(hash),
};
// Call the API.
AsymmetricSignResponse result = client.AsymmetricSign(keyVersionName, digest);
// Get the signature.
byte[] signature = result.Signature.ToByteArray();
// Return the result.
return signature;
}
}
Go
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
import (
"context"
"crypto/sha256"
"fmt"
"hash/crc32"
"io"
kms "cloud.google.com/go/kms/apiv1"
"cloud.google.com/go/kms/apiv1/kmspb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
// signAsymmetric will sign a plaintext message using a saved asymmetric private
// key stored in Cloud KMS.
func signAsymmetric(w io.Writer, name string, message string) error {
// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"
// message := "my message"
// Create the client.
ctx := context.Background()
client, err := kms.NewKeyManagementClient(ctx)
if err != nil {
return fmt.Errorf("failed to create kms client: %v", err)
}
defer client.Close()
// Convert the message into bytes. Cryptographic plaintexts and
// ciphertexts are always byte arrays.
plaintext := []byte(message)
// Calculate the digest of the message.
digest := sha256.New()
if _, err := digest.Write(plaintext); err != nil {
return fmt.Errorf("failed to create digest: %v", err)
}
// Optional but recommended: Compute digest's CRC32C.
crc32c := func(data []byte) uint32 {
t := crc32.MakeTable(crc32.Castagnoli)
return crc32.Checksum(data, t)
}
digestCRC32C := crc32c(digest.Sum(nil))
// Build the signing request.
//
// Note: Key algorithms will require a varying hash function. For example,
// EC_SIGN_P384_SHA384 requires SHA-384.
req := &kmspb.AsymmetricSignRequest{
Name: name,
Digest: &kmspb.Digest{
Digest: &kmspb.Digest_Sha256{
Sha256: digest.Sum(nil),
},
},
DigestCrc32C: wrapperspb.Int64(int64(digestCRC32C)),
}
// Call the API.
result, err := client.AsymmetricSign(ctx, req)
if err != nil {
return fmt.Errorf("failed to sign digest: %v", err)
}
// Optional, but recommended: perform integrity verification on result.
// For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
// https://cloud.google.com/kms/docs/data-integrity-guidelines
if result.VerifiedDigestCrc32C == false {
return fmt.Errorf("AsymmetricSign: request corrupted in-transit")
}
// TODO(iamtamjam) Uncomment when this field is populated by the server
// if result.Name != req.Name {
// return fmt.Errorf("AsymmetricSign: request corrupted in-transit")
// }
if int64(crc32c(result.Signature)) != result.SignatureCrc32C.Value {
return fmt.Errorf("AsymmetricSign: response corrupted in-transit")
}
fmt.Fprintf(w, "Signed digest: %s", result.Signature)
return nil
}
Java
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
import com.google.cloud.kms.v1.AsymmetricSignResponse;
import com.google.cloud.kms.v1.CryptoKeyVersionName;
import com.google.cloud.kms.v1.Digest;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
public class SignAsymmetric {
public void signAsymmetric() throws IOException, GeneralSecurityException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
String locationId = "us-east1";
String keyRingId = "my-key-ring";
String keyId = "my-key";
String keyVersionId = "123";
String message = "my message";
signAsymmetric(projectId, locationId, keyRingId, keyId, keyVersionId, message);
}
// Get the public key associated with an asymmetric key.
public void signAsymmetric(
String projectId,
String locationId,
String keyRingId,
String keyId,
String keyVersionId,
String message)
throws IOException, GeneralSecurityException {
// 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 (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {
// Build the key version name from the project, location, key ring, key,
// and key version.
CryptoKeyVersionName keyVersionName =
CryptoKeyVersionName.of(projectId, locationId, keyRingId, keyId, keyVersionId);
// Convert the message into bytes. Cryptographic plaintexts and
// ciphertexts are always byte arrays.
byte[] plaintext = message.getBytes(StandardCharsets.UTF_8);
// Calculate the digest.
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] hash = sha256.digest(plaintext);
// Build the digest object.
Digest digest = Digest.newBuilder().setSha256(ByteString.copyFrom(hash)).build();
// Sign the digest.
AsymmetricSignResponse result = client.asymmetricSign(keyVersionName, digest);
// Get the signature.
byte[] signature = result.getSignature().toByteArray();
System.out.printf("Signature %s%n", signature);
}
}
}
Node.js
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
//
// 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 message = Buffer.from('...');
// Imports the Cloud KMS library
const {KeyManagementServiceClient} = require('@google-cloud/kms');
// Instantiates a client
const client = new KeyManagementServiceClient();
// Build the version name
const versionName = client.cryptoKeyVersionPath(
projectId,
locationId,
keyRingId,
keyId,
versionId
);
async function signAsymmetric() {
// Create a digest of the message. The digest needs to match the digest
// configured for the Cloud KMS key.
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update(message);
const digest = hash.digest();
// Optional but recommended: Compute digest's CRC32C.
// Ensure fast-crc32c has been installed, `npm i fast-crc32c`.
const crc32c = require('fast-crc32c');
const digestCrc32c = crc32c.calculate(digest);
// Sign the message with Cloud KMS
const [signResponse] = await client.asymmetricSign({
name: versionName,
digest: {
sha256: digest,
},
digestCrc32c: {
value: digestCrc32c,
},
});
// Optional, but recommended: perform integrity verification on signResponse.
// For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
// https://cloud.google.com/kms/docs/data-integrity-guidelines
if (signResponse.name !== versionName) {
throw new Error('AsymmetricSign: request corrupted in-transit');
}
if (!signResponse.verifiedDigestCrc32c) {
throw new Error('AsymmetricSign: request corrupted in-transit');
}
if (
crc32c.calculate(signResponse.signature) !==
Number(signResponse.signatureCrc32c.value)
) {
throw new Error('AsymmetricSign: response corrupted in-transit');
}
// 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.
const encoded = signResponse.signature.toString('base64');
console.log(`Signature: ${encoded}`);
return signResponse.signature;
}
return signAsymmetric();
PHP
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
use Google\Cloud\Kms\V1\KeyManagementServiceClient;
use Google\Cloud\Kms\V1\Digest;
function sign_asymmetric(
string $projectId = 'my-project',
string $locationId = 'us-east1',
string $keyRingId = 'my-key-ring',
string $keyId = 'my-key',
string $versionId = '123',
string $message = '...'
) {
// Create the Cloud KMS client.
$client = new KeyManagementServiceClient();
// Build the key version name.
$keyVersionName = $client->cryptoKeyVersionName($projectId, $locationId, $keyRingId, $keyId, $versionId);
// Calculate the hash.
$hash = hash('sha256', $message, true);
// Build the digest.
//
// Note: Key algorithms will require a varying hash function. For
// example, EC_SIGN_P384_SHA384 requires SHA-384.
$digest = (new Digest())
->setSha256($hash);
// Call the API.
$signResponse = $client->asymmetricSign($keyVersionName, $digest);
printf('Signature: %s' . PHP_EOL, $signResponse->getSignature());
return $signResponse;
}
Python
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
def sign_asymmetric(project_id, location_id, key_ring_id, key_id, version_id, message):
"""
Sign a message using the public 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').
message (string): Message to sign.
Returns:
AsymmetricSignResponse: Signature.
"""
# Import the client library.
from google.cloud import kms
# Import base64 for printing the ciphertext.
import base64
# Import hashlib for calculating hashes.
import hashlib
# 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.
message_bytes = message.encode('utf-8')
# Calculate the hash.
hash_ = hashlib.sha256(message_bytes).digest()
# Build the digest.
#
# Note: Key algorithms will require a varying hash function. For
# example, EC_SIGN_P384_SHA384 requires SHA-384.
digest = {'sha256': hash_}
# Optional, but recommended: compute digest's CRC32C.
# See crc32c() function defined below.
digest_crc32c = crc32c(hash_)
# Call the API
sign_response = client.asymmetric_sign(
request={'name': key_version_name, 'digest': digest, 'digest_crc32c': digest_crc32c})
# Optional, but recommended: perform integrity verification on sign_response.
# For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
# https://cloud.google.com/kms/docs/data-integrity-guidelines
if not sign_response.verified_digest_crc32c:
raise Exception('The request sent to the server was corrupted in-transit.')
if not sign_response.name == key_version_name:
raise Exception('The request sent to the server was corrupted in-transit.')
if not sign_response.signature_crc32c == crc32c(sign_response.signature):
raise Exception('The response received from the server was corrupted in-transit.')
# End integrity verification
print('Signature: {}'.format(base64.b64encode(sign_response.signature)))
return sign_response
def crc32c(data):
"""
Calculates the CRC32C checksum of the provided data.
Args:
data: the bytes over which the checksum should be calculated.
Returns:
An int representing the CRC32C checksum of the provided bytes.
"""
import crcmod
import six
crc32c_fun = crcmod.predefined.mkPredefinedCrcFun('crc-32c')
return crc32c_fun(six.ensure_binary(data))
Ruby
Cloud KMS용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud KMS 클라이언트 라이브러리를 참조하세요.
# 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"
# message = "my message"
# 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_path project: project_id,
location: location_id,
key_ring: key_ring_id,
crypto_key: key_id,
crypto_key_version: version_id
# Calculate the hash.
#
# Note: Key algorithms will require a varying hash function. For
# example, EC_SIGN_P384_SHA384 requires SHA-384.
digest = { sha256: Digest::SHA256.digest(message) }
# Call the API.
sign_response = client.asymmetric_sign name: key_version_name, digest: digest
puts "Signature: #{Base64.strict_encode64 sign_response.signature}"
다음 단계
다른 Google Cloud 제품의 코드 샘플을 검색하고 필터링하려면 Google Cloud 샘플 브라우저를 참조하세요.