Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Ejemplo de operaciones sin conexión
Tras descargar la clave pública de su par de KMS claves asimétricas, puede compartirla con otras personas y utilizarla para realizar operaciones sin conexión.
AWS CloudTrail los registros que registran todas las AWS KMS operaciones, incluidas la solicitud, la respuesta, la fecha, la hora y el usuario autorizado, no registran el uso de la clave pública fuera de AWS KMS ella.
En este tema se proporcionan ejemplos de operaciones sin conexión y se detallan las herramientas que AWS KMS proporcionan para facilitar las operaciones sin conexión.
Temas
Obtención de secretos compartidos sin conexión
Puede descargar la clave pública de su par de ECC claves para utilizarla en operaciones fuera de línea, es decir, operaciones fuera de AWS KMS.
En el siguiente SSL tutorial de Open
-
Cree un ECC key pair en Open SSL y prepárelo para usarlo con él 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"`
-
Cree un par de ECC claves de acuerdo de claves AWS KMS y prepárelo para usarlo con 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}
-
Obtenga el secreto compartido en Open SSL utilizando la clave privada de Open SSL y la KMS clave pública.
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}
Verificación fuera de línea con pares de SM2 claves (solo en las regiones de China)
Para verificar una firma fuera o AWS KMS con una clave SM2 pública, debes especificar el identificador distintivo. Al pasar un mensaje sin procesar MessageType:RAW
, el signo AWS KMS utiliza el identificador distintivo predeterminado API1234567812345678
, definido OSCCA en la GM/T 0009-2012. No puede especificar su propio identificador distintivo en AWS KMS.
Sin embargo, si va a generar un resumen del mensaje fuera de AWS, puede especificar su propio identificador distintivo y, a continuación, pasar el resumen del mensaje, a, para que lo firme. MessageType:DIGEST
AWS KMS Para ello, cambie el valor DEFAULT_DISTINGUISHING_ID
en la clase SM2OfflineOperationHelper
. El identificador distintivo que especifique puede ser cualquier cadena de hasta 8192 caracteres. Después de AWS KMS firmar el resumen del mensaje, necesitará el resumen del mensaje o el mensaje y el identificador que se usaron para calcular el resumen para verificarlo sin conexión.
importante
El código de referencia SM2OfflineOperationHelper
está diseñado para ser compatible con Bouncy Castle
Clase SM2OfflineOperationHelper
Para ayudarle a realizar operaciones con SM2 claves fuera de línea, la SM2OfflineOperationHelper
clase de Java tiene métodos que realizan las tareas por usted. Puede usar esta clase auxiliar como modelo para otros proveedores de cifrado.
En su interior AWS KMS, las conversiones de texto cifrado sin procesar y los cálculos de los resúmenes de los SM2DSA mensajes se realizan automáticamente. No todos los proveedores de criptografía lo implementan de la SM2 misma manera. Algunas bibliotecas, como SSL las versiones 1.1.1 y posteriores de OpenSM2OfflineOperationHelper
con bibliotecas, como Bouncy Castle
La clase SM2OfflineOperationHelper
proporciona métodos para las siguientes operaciones fuera de línea:
-
- Cálculo del resumen del mensaje
-
Para generar un resumen de mensajes sin conexión que puedas usar para la verificación sin conexión o al que puedas pasar AWS KMS para firmar, usa
calculateSM2Digest
este método. ElcalculateSM2Digest
método genera un resumen del mensaje con el algoritmo SM3 de hash. GetPublicKeyAPIDevuelve la clave pública en formato binario. Debe analizar la clave binaria para convertirla en Java PublicKey. Proporcione la clave pública analizada con el mensaje. El método combina automáticamente el mensaje con el identificador distintivo predeterminado,1234567812345678
, pero puede establecer su propio identificador distintivo cambiando el valorDEFAULT_DISTINGUISHING_ID
.
-
- Verificar
-
Para verificar una firma sin conexión, utilice el método
offlineSM2DSAVerify
. El métodoofflineSM2DSAVerify
utiliza el resumen del mensaje calculado a partir del identificador distintivo especificado y el mensaje original que proporciona para verificar la firma digital. GetPublicKeyAPIDevuelve su clave pública en formato binario. Debe analizar la clave binaria para convertirla en Java PublicKey. Proporcione la clave pública analizada con el mensaje original y la firma que desea verificar. Para obtener más información, consulte Verificación sin conexión con pares de SM2 claves.
-
- Encrypt
-
Para cifrar texto sin formato sin conexión, utilice el método
offlineSM2PKEEncrypt
. Este método garantiza que el texto cifrado esté en un formato que se AWS KMS pueda descifrar. ElofflineSM2PKEEncrypt
método cifra el texto sin formato y, a continuación, convierte el texto cifrado sin procesar generado al formato .1. SM2PKE ASN GetPublicKeyAPIDevuelve la clave pública en formato binario. Debe analizar la clave binaria para convertirla en Java PublicKey. Proporcione la clave pública analizada con el texto sin formato que desea cifrar.Si no está seguro de si necesita realizar la conversión, utilice la siguiente SSL operación de apertura para probar el formato del texto cifrado. Si se produce un error en la operación, tendrás que convertir el texto cifrado al formato .1. ASN
openssl asn1parse -inform DER -in
ciphertext.der
De forma predeterminada, la SM2OfflineOperationHelper
clase utiliza el identificador distintivo predeterminado al generar resúmenes 1234567812345678
de mensajes para las operaciones. SM2DSA
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"); } }