in DynamoDbEncryption/runtimes/java/src/main/sdkv1/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.java [394:472]
public Map<String, AttributeValue> encryptRecord(
Map<String, AttributeValue> itemAttributes,
Map<String, Set<EncryptionFlags>> attributeActionsOnEncrypt,
EncryptionContext context
) throws GeneralSecurityException {
if (attributeActionsOnEncrypt.isEmpty()) {
return itemAttributes;
}
// Copy to avoid changing anyone elses objects
itemAttributes = new HashMap<String, AttributeValue>(itemAttributes);
// Copy the attribute values into the context
context =
new EncryptionContext.Builder(context)
.withAttributeValues(itemAttributes)
.build();
Function<
EncryptionContext,
EncryptionContext
> encryptionContextOverrideOperator =
getEncryptionContextOverrideOperator();
if (encryptionContextOverrideOperator != null) {
context = encryptionContextOverrideOperator.apply(context);
}
EncryptionMaterials materials =
encryptionMaterialsProvider.getEncryptionMaterials(context);
// We need to copy this because we modify it to record other encryption details
Map<String, String> materialDescription = new HashMap<String, String>(
materials.getMaterialDescription()
);
SecretKey encryptionKey = materials.getEncryptionKey();
actualEncryption(
itemAttributes,
attributeActionsOnEncrypt,
materialDescription,
encryptionKey
);
// The description must be stored after encryption because its data
// is necessary for proper decryption.
final String signingAlgo = materialDescription.get(signingAlgorithmHeader);
DynamoDBSigner signer;
if (signingAlgo != null) {
signer = DynamoDBSigner.getInstance(signingAlgo, Utils.getRng());
} else {
signer =
DynamoDBSigner.getInstance(DEFAULT_SIGNATURE_ALGORITHM, Utils.getRng());
}
if (materials.getSigningKey() instanceof PrivateKey) {
materialDescription.put(
signingAlgorithmHeader,
signer.getSigningAlgorithm()
);
}
if (!materialDescription.isEmpty()) {
itemAttributes.put(
materialDescriptionFieldName,
marshallDescription(materialDescription)
);
}
String associatedData = "TABLE>" + context.getTableName() + "<TABLE";
byte[] signature = signer.calculateSignature(
itemAttributes,
attributeActionsOnEncrypt,
associatedData.getBytes(UTF8),
materials.getSigningKey()
);
AttributeValue signatureAttribute = new AttributeValue();
signatureAttribute.setB(ByteBuffer.wrap(signature));
itemAttributes.put(signatureFieldName, signatureAttribute);
return itemAttributes;
}