Exemples d'opérations hors ligne - AWS Key Management Service

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Exemples d'opérations hors ligne

Après avoir téléchargé la clé publique de votre paire de KMS clés asymétriques, vous pouvez la partager avec d'autres utilisateurs et l'utiliser pour effectuer des opérations hors ligne.

AWS CloudTrail les journaux qui enregistrent chaque AWS KMS opération, y compris la demande, la réponse, la date, l'heure et l'utilisateur autorisé, n'enregistrent pas l'utilisation de la clé publique en dehors de AWS KMS.

Cette rubrique fournit des exemples d'opérations hors ligne et des détails fournis par les outils AWS KMS pour faciliter les opérations hors ligne.

Découverte de secrets partagés hors ligne

Vous pouvez télécharger la clé publique de votre paire de ECC clés pour l'utiliser dans des opérations hors ligne, c'est-à-dire des opérations en dehors de AWS KMS.

La SSL procédure pas à pas Open suivante montre une méthode permettant de dériver un secret partagé en dehors de l' AWS KMS utilisation de la clé publique d'une paire de ECC KMS clés et d'une clé privée créée avec Open. SSL

  1. Créez une paire de ECC clés dans Open SSL et préparez-la pour une utilisation avec AWS KMS.

    // Create an ECC key pair in OpenSSL and save the private key in openssl_ecc_key_priv.pem export OPENSSL_CURVE_NAME="P-256" export KMS_CURVE_NAME="ECC_NIST_P256" export OPENSSL_KEY1_PRIV_PEM="openssl_ecc_key1_priv.pem" openssl ecparam -name ${OPENSSL_CURVE_NAME} -genkey -out ${OPENSSL_KEY1_PRIV_PEM} // Derive the public key from the private key export OPENSSL_KEY1_PUB_PEM="openssl_ecc_key1_pub.pem" openssl ec -in ${OPENSSL_KEY1_PRIV_PEM} -pubout -outform pem \ -out ${OPENSSL_KEY1_PUB_PEM} // View the PEM file containing the public key and extract the public key as a // Base64 encoded string into OPENSSL_KEY1_PUB_BASE64 for use with AWS KMS export OPENSSL_KEY1_PUB_BASE64=`cat ${OPENSSL_KEY1_PUB_PEM} | \ tee /dev/stderr | grep -v "PUBLIC KEY" | tr -d "\n"`
  2. Créez une ECC paire de clés d'accord AWS KMS et préparez-la pour une utilisation avec OpenSSL.

    // Create a KMS key on the same curve as the key pair from step 1 // with a key usage of KEY_AGREEMENT // Save its ARN in KMS_KEY1_ARN. export KMS_KEY1_ARN=`aws kms create-key --key-spec ${KMS_CURVE_NAME} \ --key-usage KEY_AGREEMENT | tee /dev/stderr | jq -r .KeyMetadata.Arn` // Download the public key and save the Base64-encoded version in KMS_KEY1_PUB_BASE64 export KMS_KEY1_PUB_BASE64=`aws kms get-public-key --key-id ${KMS_KEY1_ARN} | \ tee /dev/stderr | jq -r .PublicKey` // Create a PEM file for the public KMS key for use with OpenSSL export KMS_KEY1_PUB_PEM="aws_kms_ecdh_key1_pub.pem" echo "-----BEGIN PUBLIC KEY-----" > ${KMS_KEY1_PUB_PEM} echo ${KMS_KEY1_PUB_BASE64} | fold -w 64 >> ${KMS_KEY1_PUB_PEM} echo "-----END PUBLIC KEY-----" >> ${KMS_KEY1_PUB_PEM}
  3. Déterminez le secret partagé dans Open SSL à l'aide de la clé privée dans Open SSL et de la KMS clé publique.

    export OPENSSL_SHARED_SECRET1_BIN="openssl_shared_secret1.bin" openssl pkeyutl -derive -inkey ${OPENSSL_KEY1_PRIV_PEM} \ -peerkey ${KMS_KEY1_PUB_PEM} -out ${OPENSSL_SHARED_SECRET1_BIN}

Vérification hors ligne à l'aide de paires de SM2 clés (régions chinoises uniquement)

Pour vérifier une signature en dehors AWS KMS d'une clé SM2 publique, vous devez spécifier l'identifiant distinctif. Lorsque vous transmettez un message brut MessageType:RAW, le signe API AWS KMS utilise l'identifiant distinctif par défaut1234567812345678, défini par GM/T OSCCA 0009-2012. Vous ne pouvez pas spécifier votre propre ID distinctif dans AWS KMS.

Toutefois, si vous générez un résumé de message en dehors de AWS, vous pouvez spécifier votre propre identifiant distinctif, puis transmettre le résumé du message, AWS KMS à MessageType:DIGEST, pour le signer. Pour ce faire, modifiez le paramètre DEFAULT_DISTINGUISHING_ID valeur dans la clé SM2OfflineOperationHelper classe. L'ID distinctif que vous spécifiez peut être n'importe quelle chaîne de 8 192 caractères maximum. Après avoir AWS KMS signé le résumé du message, vous avez besoin soit du résumé du message, soit du message et de l'ID distinctif utilisés pour calculer le résumé afin de le vérifier hors ligne.

Important

Le SM2OfflineOperationHelper code de référence est conçu pour être compatible avec Bouncy Castle version 1.68. Pour obtenir de l'aide sur les autres versions, contactezbouncycastle.org.

classe SM2OfflineOperationHelper

Pour vous aider à effectuer des opérations hors ligne avec des SM2 clés, la SM2OfflineOperationHelper classe pour Java possède des méthodes qui exécutent les tâches à votre place. Vous pouvez utiliser cette classe d'assistance comme modèle pour d'autres fournisseurs de cryptographie.

Dans AWS KMS ce cadre, les conversions de texte chiffré brut et les calculs du résumé des SM2DSA messages sont effectués automatiquement. Tous les fournisseurs de cryptographie ne mettent pas SM2 en œuvre de la même manière. Certaines bibliothèques, comme Open SSL versions 1.1.1 et ultérieures, exécutent ces actions automatiquement. AWS KMS a confirmé ce comportement lors de tests avec Open SSL version 3.0. Utilisez les classes SM2OfflineOperationHelper avec des bibliothèques, comme Bouncy Castle, qui vous obligent à effectuer ces conversions et ces calculs manuellement.

La classe SM2OfflineOperationHelper fournit des méthodes pour les opérations hors ligne suivantes :

  • Calcul de l'algorithme Message Digest

    Pour générer un résumé de message hors ligne que vous pouvez utiliser pour la vérification hors ligne ou que vous pouvez transmettre AWS KMS pour le signer, utilisez calculateSM2Digest cette méthode. Le calculateSM2Digest procédé génère un condensé de message à l'aide de l'algorithme SM3 de hachage. GetPublicKeyAPIRenvoie votre clé publique au format binaire. Vous devez analyser la clé binaire dans un Java PublicKey. Fournissez la clé publique analysée avec le message. La méthode combine automatiquement votre message avec l'identifiant distinctif par défaut, 1234567812345678, mais vous pouvez définir votre propre ID distinctif en modifiant la valeur DEFAULT_DISTINGUISHING_ID.

  • Vérification

    Pour vérifier une signature hors ligne, utilisez la méthode offlineSM2DSAVerify. La méthode offlineSM2DSAVerify utilise le résumé du message calculé à partir de l'ID distinctif spécifié et du message d'origine que vous avez fourni pour vérifier la signature numérique. GetPublicKeyAPIRenvoie votre clé publique au format binaire. Vous devez analyser la clé binaire dans un Java PublicKey. Fournissez la clé publique analysée avec le message d'origine et la signature que vous souhaitez vérifier. Pour plus de détails, consultez la section Vérification hors ligne à l'aide de paires de SM2 clés.

  • Chiffrement

    Pour chiffrer du texte en clair hors ligne, utilisez la méthode offlineSM2PKEEncrypt. Cette méthode garantit que le texte chiffré est dans un format AWS KMS déchiffrable. La offlineSM2PKEEncrypt méthode chiffre le texte en clair, puis convertit le texte chiffré brut produit par SM2PKE au format .1. ASN GetPublicKeyAPIRenvoie votre clé publique au format binaire. Vous devez analyser la clé binaire dans un Java PublicKey. Fournissez la clé publique analysée avec le texte brut que vous souhaitez chiffrer.

    Si vous ne savez pas si vous devez effectuer la conversion, utilisez l'SSLopération Open suivante pour tester le format de votre texte chiffré. Si l'opération échoue, vous devez convertir le texte chiffré au format ASN .1.

    openssl asn1parse -inform DER -in ciphertext.der

Par défaut, la SM2OfflineOperationHelper classe utilise l'identifiant distinctif par défaut lors de la génération de résumés de messages pour SM2DSA les opérations. 1234567812345678

package com.amazon.kms.utils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.IOException; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.jce.interfaces.ECPublicKey; import java.util.Arrays; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ParametersWithID; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.SM2Signer; import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; public class SM2OfflineOperationHelper { // You can change the DEFAULT_DISTINGUISHING_ID value to set your own distinguishing ID, // the DEFAULT_DISTINGUISHING_ID can be any string up to 8,192 characters long. private static final byte[] DEFAULT_DISTINGUISHING_ID = "1234567812345678".getBytes(StandardCharsets.UTF_8); private static final X9ECParameters SM2_X9EC_PARAMETERS = GMNamedCurves.getByName("sm2p256v1"); // ***calculateSM2Digest*** // Calculate message digest public static byte[] calculateSM2Digest(final PublicKey publicKey, final byte[] message) throws NoSuchProviderException, NoSuchAlgorithmException { final ECPublicKey ecPublicKey = (ECPublicKey) publicKey; // Generate SM3 hash of default distinguishing ID, 1234567812345678 final int entlenA = DEFAULT_DISTINGUISHING_ID.length * 8; final byte [] entla = new byte[] { (byte) (entlenA & 0xFF00), (byte) (entlenA & 0x00FF) }; final byte [] a = SM2_X9EC_PARAMETERS.getCurve().getA().getEncoded(); final byte [] b = SM2_X9EC_PARAMETERS.getCurve().getB().getEncoded(); final byte [] xg = SM2_X9EC_PARAMETERS.getG().getXCoord().getEncoded(); final byte [] yg = SM2_X9EC_PARAMETERS.getG().getYCoord().getEncoded(); final byte[] xa = ecPublicKey.getQ().getXCoord().getEncoded(); final byte[] ya = ecPublicKey.getQ().getYCoord().getEncoded(); final byte[] za = MessageDigest.getInstance("SM3", "BC") .digest(ByteBuffer.allocate(entla.length + DEFAULT_DISTINGUISHING_ID.length + a.length + b.length + xg.length + yg.length + xa.length + ya.length).put(entla).put(DEFAULT_DISTINGUISHING_ID).put(a).put(b).put(xg).put(yg).put(xa).put(ya) .array()); // Combine hashed distinguishing ID with original message to generate final digest return MessageDigest.getInstance("SM3", "BC") .digest(ByteBuffer.allocate(za.length + message.length).put(za).put(message) .array()); } // ***offlineSM2DSAVerify*** // Verify digital signature with SM2 public key public static boolean offlineSM2DSAVerify(final PublicKey publicKey, final byte [] message, final byte [] signature) throws InvalidKeyException { final SM2Signer signer = new SM2Signer(); CipherParameters cipherParameters = ECUtil.generatePublicKeyParameter(publicKey); cipherParameters = new ParametersWithID(cipherParameters, DEFAULT_DISTINGUISHING_ID); signer.init(false, cipherParameters); signer.update(message, 0, message.length); return signer.verifySignature(signature); } // ***offlineSM2PKEEncrypt*** // Encrypt data with SM2 public key public static byte[] offlineSM2PKEEncrypt(final PublicKey publicKey, final byte [] plaintext) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException { final Cipher sm2Cipher = Cipher.getInstance("SM2", "BC"); sm2Cipher.init(Cipher.ENCRYPT_MODE, publicKey); // By default, Bouncy Castle returns raw ciphertext in the c1c2c3 format final byte [] cipherText = sm2Cipher.doFinal(plaintext); // Convert the raw ciphertext to the ASN.1 format before passing it to AWS KMS final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector(); final int coordinateLength = (SM2_X9EC_PARAMETERS.getCurve().getFieldSize() + 7) / 8 * 2 + 1; final int sm3HashLength = 32; final int xCoordinateInCipherText = 33; final int yCoordinateInCipherText = 65; byte[] coords = new byte[coordinateLength]; byte[] sm3Hash = new byte[sm3HashLength]; byte[] remainingCipherText = new byte[cipherText.length - coordinateLength - sm3HashLength]; // Split components out of the ciphertext System.arraycopy(cipherText, 0, coords, 0, coordinateLength); System.arraycopy(cipherText, cipherText.length - sm3HashLength, sm3Hash, 0, sm3HashLength); System.arraycopy(cipherText, coordinateLength, remainingCipherText, 0,cipherText.length - coordinateLength - sm3HashLength); // Build standard SM2PKE ASN.1 ciphertext vector asn1EncodableVector.add(new ASN1Integer(new BigInteger(1, Arrays.copyOfRange(coords, 1, xCoordinateInCipherText)))); asn1EncodableVector.add(new ASN1Integer(new BigInteger(1, Arrays.copyOfRange(coords, xCoordinateInCipherText, yCoordinateInCipherText)))); asn1EncodableVector.add(new DEROctetString(sm3Hash)); asn1EncodableVector.add(new DEROctetString(remainingCipherText)); return new DERSequence(asn1EncodableVector).getEncoded("DER"); } }