@Override public DataKey<KmsMasterKey> encryptDataKey(final CryptoAlgorithm algorithm, final Map<String, String> encryptionContext, final DataKey<?> dataKey) { final SecretKey key = dataKey.getKey(); if (!key.getFormat().equals("RAW")) { throw new IllegalArgumentException("Only RAW encoded keys are supported"); } try { final EncryptResult encryptResult = kms_.encrypt( new EncryptRequest() .withKeyId(id_) .withPlaintext(ByteBuffer.wrap(key.getEncoded())) .withEncryptionContext(encryptionContext) .withGrantTokens(grantTokens_)); final byte[] edk = new byte[encryptResult.getCiphertextBlob().remaining()]; encryptResult.getCiphertextBlob().get(edk); return new DataKey<>(dataKey.getKey(), edk, encryptResult.getKeyId().getBytes(StandardCharsets.UTF_8), this); } catch (final AmazonServiceException asex) { throw new AwsCryptoException(asex); } }
@Override public GenerateDataKeyResult generateDataKey(GenerateDataKeyRequest req) throws AmazonServiceException, AmazonClientException { byte[] pt; if (req.getKeySpec() != null) { if (req.getKeySpec().contains("256")) { pt = new byte[32]; } else if (req.getKeySpec().contains("128")) { pt = new byte[16]; } else { throw new java.lang.UnsupportedOperationException(); } } else { pt = new byte[req.getNumberOfBytes()]; } rnd.nextBytes(pt); ByteBuffer ptBuff = ByteBuffer.wrap(pt); EncryptResult encryptResult = encrypt0(new EncryptRequest().withKeyId(req.getKeyId()).withPlaintext(ptBuff) .withEncryptionContext(req.getEncryptionContext())); String arn = retrieveArn(req.getKeyId()); return new GenerateDataKeyResult().withKeyId(arn).withCiphertextBlob(encryptResult.getCiphertextBlob()) .withPlaintext(ptBuff); }
@Before public void setUp() throws Exception { mockKms = mock(AWSKMS.class); textEncryptor = new KmsTextEncryptor(mockKms, KMS_KEY_ID); expectedEncryptRequest = new EncryptRequest(); expectedEncryptRequest.setKeyId(KMS_KEY_ID); expectedEncryptRequest.setPlaintext(wrap(PLAINTEXT.getBytes())); encryptResult = new EncryptResult(); encryptResult.setCiphertextBlob(wrap(CIPHER_TEXT.getBytes())); when(mockKms.encrypt(any(EncryptRequest.class))).thenReturn(encryptResult); expectedDecryptRequest = new DecryptRequest(); expectedDecryptRequest.setCiphertextBlob(wrap(CIPHER_TEXT.getBytes())); decryptResult = new DecryptResult(); decryptResult.setPlaintext(wrap(PLAINTEXT.getBytes())); when(mockKms.decrypt(any(DecryptRequest.class))).thenReturn(decryptResult); }
@Override public GenerateDataKeyResult generateDataKey(GenerateDataKeyRequest req) throws AmazonServiceException, AmazonClientException { byte[] pt; if (req.getKeySpec() != null) { if (req.getKeySpec().contains("256")) { pt = new byte[32]; } else if (req.getKeySpec().contains("128")) { pt = new byte[16]; } else { throw new UnsupportedOperationException(); } } else { pt = new byte[req.getNumberOfBytes()]; } rnd.nextBytes(pt); ByteBuffer ptBuff = ByteBuffer.wrap(pt); EncryptResult encryptResult = encrypt(new EncryptRequest().withKeyId(req.getKeyId()) .withPlaintext(ptBuff).withEncryptionContext(req.getEncryptionContext())); return new GenerateDataKeyResult().withKeyId(req.getKeyId()) .withCiphertextBlob(encryptResult.getCiphertextBlob()).withPlaintext(ptBuff); }
@Test public void testEncryptDecrypt() throws Exception { DecryptResult mockDecryptResult = mock(DecryptResult.class); EncryptResult mockEncryptResult = mock(EncryptResult.class); when(mockKms.decrypt(isA(DecryptRequest.class))) .thenReturn(mockDecryptResult); when(mockKms.encrypt(isA(EncryptRequest.class))) .thenReturn(mockEncryptResult); Aead aead = new AwsKmsAead(mockKms, keyId); byte[] aad = Random.randBytes(20); for (int messageSize = 0; messageSize < 75; messageSize++) { byte[] message = Random.randBytes(messageSize); when(mockDecryptResult.getPlaintext()).thenReturn(ByteBuffer.wrap(message)); when(mockEncryptResult.getCiphertextBlob()).thenReturn(ByteBuffer.wrap(message)); byte[] ciphertext = aead.encrypt(message, aad); byte[] decrypted = aead.decrypt(ciphertext, aad); assertArrayEquals(message, decrypted); } }
@Test public void testDecrypt_shouldThrowExceptionIfRequestFailed() throws Exception { EncryptResult mockEncryptResult = mock(EncryptResult.class); when(mockKms.encrypt(isA(EncryptRequest.class))) .thenReturn(mockEncryptResult); AmazonServiceException exception = mock(AmazonServiceException.class); when(mockKms.decrypt(isA(DecryptRequest.class))) .thenThrow(exception); Aead aead = new AwsKmsAead(mockKms, keyId); byte[] aad = Random.randBytes(20); byte[] message = Random.randBytes(20); when(mockEncryptResult.getCiphertextBlob()).thenReturn(ByteBuffer.wrap(message)); byte[] ciphertext = aead.encrypt(message, aad); try { aead.decrypt(ciphertext, aad); fail("Expected GeneralSecurityException"); } catch (GeneralSecurityException e) { // expected. } }
/** * Encrypts the data provided using KMS based on the provided region and key id. * * @param regionName Region where key is located * @param keyId Key id * @param data Data to be encrypted * @return encrypted data */ private byte[] encrypt(final String regionName, final String keyId, final byte[] data) { Region region; try { region = Region.getRegion(Regions.fromName(regionName)); } catch (IllegalArgumentException iae) { throw ApiException.newBuilder() .withApiErrors(DefaultApiError.AUTH_IAM_ROLE_AWS_REGION_INVALID) .withExceptionCause(iae) .build(); } final AWSKMSClient kmsClient = kmsClientFactory.getClient(region); try { final EncryptResult encryptResult = kmsClient.encrypt(new EncryptRequest().withKeyId(keyId).withPlaintext(ByteBuffer.wrap(data))); return encryptResult.getCiphertextBlob().array(); } catch (AmazonClientException ace) { throw ApiException.newBuilder() .withApiErrors(DefaultApiError.INTERNAL_SERVER_ERROR) .withExceptionCause(ace) .withExceptionMessage( String.format("Unexpected error communicating with AWS KMS for region %s.", regionName)) .build(); } }
private EncryptResult encrypt0(EncryptRequest req) throws AmazonServiceException, AmazonClientException { final byte[] cipherText = new byte[512]; rnd.nextBytes(cipherText); DecryptResult dec = new DecryptResult(); dec.withKeyId(req.getKeyId()).withPlaintext(req.getPlaintext().asReadOnlyBuffer()); ByteBuffer ctBuff = ByteBuffer.wrap(cipherText); results_.put(new DecryptMapKey(ctBuff, req.getEncryptionContext()), dec); String arn = retrieveArn(req.getKeyId()); return new EncryptResult().withCiphertextBlob(ctBuff).withKeyId(arn); }
/** * Using the given AWS Key, encrypt the given bytes * * @param awsKeyId unique identifier for the customer master key * @param clearBytes the unencrypted bytes to encrypt * @return the encrypted bytes */ public static byte[] encrypt(String awsKeyId, Map<String, String> encryptionContext, byte[] clearBytes) { EncryptRequest encryptRequest = new EncryptRequest(); encryptRequest.setKeyId(awsKeyId); encryptRequest.setPlaintext(ByteBuffer.wrap(clearBytes)); encryptRequest.setEncryptionContext(encryptionContext); AWSKMSClient client = new AWSKMSClient(); EncryptResult encryptResult = client.encrypt(encryptRequest); return encryptResult.getCiphertextBlob().array(); }
@Override public EncryptResult encrypt(EncryptRequest req) throws AmazonServiceException, AmazonClientException { final byte[] cipherText = new byte[512]; rnd.nextBytes(cipherText); DecryptResult dec = new DecryptResult(); dec.withKeyId(req.getKeyId()).withPlaintext(req.getPlaintext().asReadOnlyBuffer()); ByteBuffer ctBuff = ByteBuffer.wrap(cipherText); results_.put(new DecryptMapKey(ctBuff, req.getEncryptionContext()), dec); return new EncryptResult().withCiphertextBlob(ctBuff).withKeyId(req.getKeyId()); }
public EncryptResult encrypt(EncryptRequest request) { // Default AWS limit was 1200 shared as of Aug 2017 return execute("KmsEncryptDecrypt", "KmsEncrypt", () -> client.encrypt(request)); }
@Override public EncryptResult encrypt(EncryptRequest req) throws AmazonServiceException, AmazonClientException { // We internally delegate to encrypt, so as to avoid mockito detecting extra calls to encrypt when spying on the // MockKMSClient, we put the real logic into a separate function. return encrypt0(req); }
private String kmsEncrypt(String value) { String kmsKeyId = context.getSecrets().getSecret("aws.emr.kms_key_id"); EncryptResult result = kms.encrypt(new EncryptRequest().withKeyId(kmsKeyId).withPlaintext(UTF_8.encode(value))); return base64(result.getCiphertextBlob()); }