Import keys - AWS Payment Cryptography

Import keys

Important

Examples may require the latest version of the AWS CLI V2. Before getting started, please ensure that you have upgraded to the latest version.

Importing symmetric keys

Import keys using asymmetric techniques (TR-34)

AWS Payment Cryptography key encryption key import process

Overview: TR-34 utilizes RSA asymmetric cryptography to encrypt symmetric keys for exchange as well as ensuring the source of the data (signing). This ensures both the confidentiality (encryption) and integrity (signature) of the wrapped key.

If you would like to import your own keys, please check out the sample project on Github. For instructions on how to import/export keys from other platforms, please consult the user guide for those platforms.

1. Call the initialize import command

Call get-parameters-for-import to initialize the import process. This API will generate a keypair for the purpose of key imports, sign the key and return back the certificate and certificate root. Ultimately, the key to be exported should be encrypted using this key. In TR-34 terminology, this is known as the KRD Cert. Note that these certificates are short lived and are only intended for this purpose.

2. Install public certificate on key source system

With many HSMs, you may need to install/load/trust the public certificate generated in step 1 in order to export keys using it.

3. Generate public key and provide certificate root to AWS Payment Cryptography

To ensure integrity of the transmitted payload, it is signed by the sending party (known as the Key Distribution Host or KDH). The sending party will want to generate a public key for this purpose and then create a public key certificate (X509) that can be provided back to AWS Payment Cryptography. AWS Private CA is one option for generating certificates, but there is no restrictions on the certificate authority used.

Once you have the certificate, you'll want to load the root certificate to AWS Payment Cryptography using the importKey command and KeyMaterialType of ROOT_PUBLIC_KEY_CERTIFICATE and KeyUsageType of TR31_S0_ASYMMETRIC_KEY_FOR_DIGITAL_SIGNATURE.

4. Export key from source system

Many HSMs and related systems support the ability to export keys using the TR-34 norm. You'll want to specify the public key from step 1 as the KRD (encryption) cert and the key from step 3 as the KDH (signing) cert. In order to import to AWS Payment Cryptography, you'll want to specify the format to be TR-34.2012 non-CMS two pass format which may also be referred to as the TR-34 Diebold format.

5. Call import key

As the last step, you will call the importKey API with a KeyMaterialType of TR34_KEY_BLOCK. The certificate-authority-public-key-identifier will be the keyARN of the root CA imported in step 3, key-material will be wrapped key material from step 4 and signing-key-certificate is the leaf certificate from step 3. You will also need to provide the import-token from step 1.

6. Use imported key for cryptographic operations or subsequent import

If the imported KeyUsage was TR31_K0_KEY_ENCRYPTION_KEY, then this key can be used for subsequent key imports using TR-31. If the key type was any other type (such as TR31_D0_SYMMETRIC_DATA_ENCRYPTION_KEY), then the key can be directly used for cryptographic operations.

Import keys using asymmetric techniques (RSA Unwrap)

Overview: AWS Payment Cryptography supports RSA wrap/unwrap for key exchange when TR-34 is not feasible. Similar to TR-34, this technique utilizes RSA asymmetric cryptography to encrypt symmetric keys for exchange. However, unlike TR-34, this method does not have the payload signed by the sending party. Also, this RSA wrap technique does not maintain the integrity of the key metadata during transfer by virtue of not including key blocks.

Note

RSA wrap can be used to import or export TDES and AES-128 keys.

1. Call the initialize import command

Call get-parameters-for-import to initialize the import process with a key material type of KEY_CRYPTOGRAM. WrappingKeyAlgorithm can be RSA_2048 when exchanging TDES keys. RSA_3072 or RSA_4096 can be used when exchanging TDES or AES-128 keys. This API will generate a keypair for the purpose of key imports, sign the key using a certificate root and return back both the certificate and certificate root. Ultimately, the key to be exported should be encrypted using this key. Note that these certificates are short lived and are only intended for this purpose.

$ aws payment-cryptography get-parameters-for-import --key-material-type KEY_CRYPTOGRAM --wrapping-key-algorithm RSA_4096
{ "ImportToken": "import-token-bwxli6ocftypneu5", "ParametersValidUntilTimestamp": 1698245002.065, "WrappingKeyCertificateChain": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0....", "WrappingKeyCertificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0....", "WrappingKeyAlgorithm": "RSA_4096" }
2. Install public certificate on key source system

With many HSMs, you may need to install/load/trust the public certificate(and/or its root) generated in step 1 in order to export keys using it.

3. Export key from source system

Many HSMs and related systems support the ability to export keys using RSA wrap. You'll want to specify the public key from step 1 as the (encryption) cert (WrappingKeyCertificate). If you need the chain of trust, this is contained in the response field WrappingKeyCertificateChain in step #1. When exporting the key from your HSM, you'll want to specify the format to be RSA, Padding Mode = PKCS#1 v2.2 OAEP (with SHA 256 or SHA 512).

4. Call import key

As the last step, you will call the importKey API with a KeyMaterialType of KeyMaterial. You will need the import-token from step 1 and the key-material (wrapped key material) from step 3. You will need to provide the key parameters (such as Key Usage) since RSA wrap does not utilize key blocks.

$ cat import-key-cryptogram.json { "KeyMaterial": { "KeyCryptogram": { "Exportable": true, "ImportToken": "import-token-bwxli6ocftypneu5", "KeyAttributes": { "KeyAlgorithm": "AES_128", "KeyClass": "SYMMETRIC_KEY", "KeyModesOfUse": { "Decrypt": true, "DeriveKey": false, "Encrypt": true, "Generate": false, "NoRestrictions": false, "Sign": false, "Unwrap": true, "Verify": false, "Wrap": true }, "KeyUsage": "TR31_K0_KEY_ENCRYPTION_KEY" }, "WrappedKeyCryptogram": "18874746731....", "WrappingSpec": "RSA_OAEP_SHA_256" } } }
$ aws payment-cryptography import-key --cli-input-json file://import-key-cryptogram.json
{ "Key": { "KeyOrigin": "EXTERNAL", "Exportable": true, "KeyCheckValue": "DA1ACF", "UsageStartTimestamp": 1697643478.92, "Enabled": true, "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/kwapwa6qaifllw2h", "CreateTimestamp": 1697643478.92, "KeyState": "CREATE_COMPLETE", "KeyAttributes": { "KeyAlgorithm": "AES_128", "KeyModesOfUse": { "Encrypt": true, "Unwrap": true, "Verify": false, "DeriveKey": false, "Decrypt": true, "NoRestrictions": false, "Sign": false, "Wrap": true, "Generate": false }, "KeyUsage": "TR31_K0_KEY_ENCRYPTION_KEY", "KeyClass": "SYMMETRIC_KEY" }, "KeyCheckValueAlgorithm": "CMAC" } }
5. Use imported key for cryptographic operations or subsequent import

If the imported KeyUsage was TR31_K0_KEY_ENCRYPTION_KEY, then this key can be used for subsequent key imports using TR-31. If the key type was any other type (such as TR31_D0_SYMMETRIC_DATA_ENCRYPTION_KEY), then the key can be directly used for cryptographic operations.

Import symmetric keys using a pre-established key exchange key (TR-31)

AWS Payment Cryptography symmetric key import process

When partners are exchanging multiple keys (or to support key rotation), it is typical to first exchange an initial key encryption key (KEK) using techniques such as paper key components or in the case of AWS Payment Cryptography using TR-34.

Once a KEK is established, you can use this key to transport subsequent keys (including other KEKs). AWS Payment Cryptography supports this kind of key exchange using ANSI TR-31 which is widely used and widely supported by HSM vendors.

1. Import Key Encryption Key (KEK)

It is assumed that you've already imported your KEK and have the keyARN (or keyAlias) available to you.

2. Create key on source platform

If the key doesn't already exist, create the key on the source platform. Conversely, you can create the key on AWS Payment Cryptography and use the export command instead.

3. Export key from source platform

When exporting, ensure that you specify the export format as TR-31. The source platform will also ask you for the key to be exported and the key encryption key to use.

4. Import into AWS Payment Cryptography

When calling the importKey command, WrappingKeyIdentifier should be the keyARN (or alias) of your key encryption key and WrappedKeyBlock is the output from the source platform.

$ aws payment-cryptography import-key \ --key-material="Tr31KeyBlock={WrappingKeyIdentifier="arn:aws:payment-cryptography:us-east-2:111122223333:key/ov6icy4ryas4zcza",\ WrappedKeyBlock="D0112B0AX00E00002E0A3D58252CB67564853373D1EBCC1E23B2ADE7B15E967CC27B85D5999EF58E11662991FF5EB1381E987D744334B99D"}"
{ "Key": { "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/kwapwa6qaifllw2h", "KeyAttributes": { "KeyUsage": "TR31_D0_SYMMETRIC_DATA_ENCRYPTION_KEY", "KeyClass": "SYMMETRIC_KEY", "KeyAlgorithm": "AES_128", "KeyModesOfUse": { "Encrypt": true, "Decrypt": true, "Wrap": true, "Unwrap": true, "Generate": false, "Sign": false, "Verify": false, "DeriveKey": false, "NoRestrictions": false } }, "KeyCheckValue": "0A3674", "KeyCheckValueAlgorithm": "CMAC", "Enabled": true, "Exportable": true, "KeyState": "CREATE_COMPLETE", "KeyOrigin": "EXTERNAL", "CreateTimestamp": "2023-06-02T07:38:14.913000-07:00", "UsageStartTimestamp": "2023-06-02T07:38:14.857000-07:00" } }

Importing asymmetric (RSA) keys

Importing RSA public keys

AWS Payment Cryptography supports importing public RSA keys in the form of X.509 certificates. In order to import a certificate, you will need to first import its root certificate. All certificates should be unexpired at the time of import. The certificate should be in PEM format and should be base64 encoded.

1. Import into Root Certificate into AWS Payment Cryptography
$ aws payment-cryptography import-key \ --key-material='{"RootCertificatePublicKey":{"KeyAttributes":{"KeyAlgorithm":"RSA_2048", \ "KeyClass":"PUBLIC_KEY", "KeyModesOfUse":{"Verify": true},"KeyUsage":"TR31_S0_ASYMMETRIC_KEY_FOR_DIGITAL_SIGNATURE"}, \ "PublicKeyCertificate":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKVENDQWcyZ0F3SUJBZ0lCWkRBTkJna3Foa2lHOXcwQkFR..."}}'
{ "Key": { "CreateTimestamp": "2023-08-08T18:52:01.023000+00:00", "Enabled": true, "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/zabouwe3574jysdl", "KeyAttributes": { "KeyAlgorithm": "RSA_2048", "KeyClass": "PUBLIC_KEY", "KeyModesOfUse": { "Decrypt": false, "DeriveKey": false, "Encrypt": false, "Generate": false, "NoRestrictions": false, "Sign": false, "Unwrap": false, "Verify": true, "Wrap": false }, "KeyUsage": "TR31_S0_ASYMMETRIC_KEY_FOR_DIGITAL_SIGNATURE" }, "KeyOrigin": "EXTERNAL", "KeyState": "CREATE_COMPLETE", "UsageStartTimestamp": "2023-08-08T18:52:01.023000+00:00" } }
2. Import Public Key Certificate into AWS Payment Cryptography

You can now import a public key. There are two options for importing public keys. TR31_S0_ASYMMETRIC_KEY_FOR_DIGITAL_SIGNATURE can be used if the purpose of the key is to verify signatures (for instance when importing using TR-34). TR31_D1_ASYMMETRIC_KEY_FOR_DATA_ENCRYPTION can be used when encrypting data that is meant for use with another system.

$ aws payment-cryptography import-key \ --key-material='{"TrustedCertificatePublicKey":{"CertificateAuthorityPublicKeyIdentifier":"arn:aws:payment-cryptography:us-east-2:111122223333:key/zabouwe3574jysdl", \ "KeyAttributes":{"KeyAlgorithm":"RSA_2048","KeyClass":"PUBLIC_KEY","KeyModesOfUse":{"Verify":true},"KeyUsage":"TR31_S0_ASYMMETRIC_KEY_FOR_DIGITAL_SIGNATURE"},\ "PublicKeyCertificate":"LS0tLS1CRUdJTiB..."}}'
{ "Key": { "CreateTimestamp": "2023-08-08T18:55:46.815000+00:00", "Enabled": true, "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/4kd6xud22e64wcbk", "KeyAttributes": { "KeyAlgorithm": "RSA_4096", "KeyClass": "PUBLIC_KEY", "KeyModesOfUse": { "Decrypt": false, "DeriveKey": false, "Encrypt": false, "Generate": false, "NoRestrictions": false, "Sign": false, "Unwrap": false, "Verify": true, "Wrap": false }, "KeyUsage": "TR31_S0_ASYMMETRIC_KEY_FOR_DIGITAL_SIGNATURE" }, "KeyOrigin": "EXTERNAL", "KeyState": "CREATE_COMPLETE", "UsageStartTimestamp": "2023-08-08T18:55:46.815000+00:00" } }