Esempi di operazioni offline - AWS Key Management Service

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Esempi di operazioni offline

Dopo aver scaricato la chiave pubblica della tua coppia di KMS chiavi asimmetriche, puoi condividerla con altri e utilizzarla per eseguire operazioni offline.

AWS CloudTrail i registri che registrano ogni AWS KMS operazione, inclusa la richiesta, la risposta, la data, l'ora e l'utente autorizzato, non registrano l'uso della chiave pubblica all'esterno di. AWS KMS

Questo argomento fornisce esempi di operazioni offline e dettagli sugli strumenti AWS KMS forniti per semplificare le operazioni offline.

Ricevere segreti condivisi offline

È possibile scaricare la chiave pubblica della propria coppia di ECC chiavi per utilizzarla in operazioni offline, ovvero operazioni esterne a AWS KMS.

La seguente SSL procedura dettagliata di Open illustra un metodo per derivare un segreto condiviso oltre all' AWS KMS utilizzo della chiave pubblica di una coppia di chiavi e di una ECC KMS chiave privata creata con Open. SSL

  1. Crea una ECC key pair in Open SSL e preparala per l'uso con 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. Crea una coppia di ECC chiavi per l'accordo chiave AWS KMS e preparala per l'uso 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}
  3. Ricava un segreto condiviso in Open SSL utilizzando la chiave privata in Open SSL e la KMS chiave pubblica.

    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}

Verifica offline con coppie di SM2 chiavi (solo regioni cinesi)

Per verificare una firma all'esterno AWS KMS con una chiave SM2 pubblica, devi specificare l'ID distintivo. Quando si passa un messaggio non elaborato MessageType:RAW, a SignAPI, viene AWS KMS utilizzato l'ID distintivo predefinito1234567812345678, definito OSCCA in GM/T 0009-2012. Non puoi specificare il tuo ID distintivo all’interno di AWS KMS.

Tuttavia, se stai generando un digest del messaggio all'esterno di AWS, puoi specificare il tuo ID distintivo, quindi passare il digest del messaggio,, a to sign. MessageType:DIGEST AWS KMS A tale scopo, modifica il valore DEFAULT_DISTINGUISHING_ID in classe SM2OfflineOperationHelper. L'ID distintivo specificato può essere qualsiasi stringa lunga fino a 8.192 caratteri. Dopo aver AWS KMS firmato il digest del messaggio, è necessario il message digest o il messaggio e l'ID distintivo utilizzati per calcolare il digest per verificarlo offline.

Importante

Il codice di riferimento SM2OfflineOperationHelper è progettato per essere compatibile con Bouncy Castle versione 1.68. Per assistenza con altre versioni, contatta bouncycastle.org.

Classe SM2OfflineOperationHelper

Per aiutarvi con le operazioni offline con le SM2 chiavi, la SM2OfflineOperationHelper classe per Java dispone di metodi che eseguono le attività al posto vostro. È possibile utilizzare questa classe helper come modello per altri fornitori di crittografia.

All'interno AWS KMS, le conversioni di testo cifrato non elaborato e i calcoli del SM2DSA message digest avvengono automaticamente. Non tutti i provider di crittografia implementano SM2 allo stesso modo. Alcune librerie, come SSL le versioni Open 1.1.1 e successive, eseguono queste azioni automaticamente. AWS KMS ha confermato questo comportamento durante i test con la SSL versione 3.0 di Open. Utilizza la seguente classe SM2OfflineOperationHelper con librerie, come Bouncy Castle, che richiedono di eseguire manualmente queste conversioni e calcoli.

La classe SM2OfflineOperationHelper fornisce metodi per le seguenti operazioni offline:

  • Calcolo del digest del messaggio

    Per generare un riepilogo dei messaggi offline da utilizzare per la verifica offline o da passare AWS KMS alla firma, utilizza il calculateSM2Digest metodo. Il calculateSM2Digest metodo genera un digest dei messaggi con l'algoritmo di SM3 hashing. GetPublicKeyAPIRestituisce la chiave pubblica in formato binario. È necessario analizzare la chiave binaria in un file Java PublicKey. Fornisci il messaggio alla chiave pubblica analizzata. Il metodo combina automaticamente il tuo messaggio con l'ID distintivo predefinito, 1234567812345678, ma è possibile impostare il proprio ID distintivo modificando il valore DEFAULT_DISTINGUISHING_ID.

  • Verify

    Per verificare la firma offline, usa il metodo offlineSM2DSAVerify. Il metodo offlineSM2DSAVerify utilizza il digest del messaggio calcolato dall'ID distintivo specificato e il messaggio originale fornito per verificare la firma digitale. GetPublicKeyAPIRestituisce la chiave pubblica in formato binario. È necessario analizzare la chiave binaria in un file Java PublicKey. Fornisci alla chiave pubblica analizzata il messaggio originale e la firma che desideri verificare. Per maggiori dettagli, consulta Verifica offline con coppie di SM2 chiavi.

  • Encrypt

    Per crittografare il testo normale offline utilizza il metodo offlineSM2PKEEncrypt. Questo metodo garantisce che il testo cifrato sia in un formato AWS KMS decifrabile. Il offlineSM2PKEEncrypt metodo cripta il testo non crittografato e quindi converte il testo cifrato non elaborato prodotto da nel formato .1. SM2PKE ASN GetPublicKeyAPIRestituisce la chiave pubblica in formato binario. È necessario analizzare la chiave binaria in un file Java PublicKey. Fornisci alla chiave pubblica analizzata il testo normale che desideri crittografare.

    Se non siete sicuri di dover eseguire la conversione, utilizzate la seguente SSL operazione Open per testare il formato del testo cifrato. Se l'operazione fallisce, è necessario convertire il testo cifrato nel formato .1. ASN

    openssl asn1parse -inform DER -in ciphertext.der

Per impostazione predefinita, la SM2OfflineOperationHelper classe utilizza l'ID distintivo predefinito quando genera i digest 1234567812345678 dei messaggi per le operazioni. 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"); } }