public Map encryptRecord()

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;
  }