private void actualEncryption()

in sdk1/src/main/java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.java [425:477]


  private void actualEncryption(
      Map<String, AttributeValue> itemAttributes,
      Map<String, Set<EncryptionFlags>> attributeFlags,
      Map<String, String> materialDescription,
      SecretKey encryptionKey)
      throws GeneralSecurityException {
    String encryptionMode = null;
    if (encryptionKey != null) {
      materialDescription.put(this.symmetricEncryptionModeHeader, SYMMETRIC_ENCRYPTION_MODE);
      encryptionMode = encryptionKey.getAlgorithm() + SYMMETRIC_ENCRYPTION_MODE;
    }
    Cipher cipher = null;
    int blockSize = -1;

    for (Map.Entry<String, AttributeValue> entry : itemAttributes.entrySet()) {
      Set<EncryptionFlags> flags = attributeFlags.get(entry.getKey());
      if (flags != null && flags.contains(EncryptionFlags.ENCRYPT)) {
        if (!flags.contains(EncryptionFlags.SIGN)) {
          throw new IllegalArgumentException(
              "All encrypted fields must be signed. Bad field: " + entry.getKey());
        }
        ByteBuffer plainText = AttributeValueMarshaller.marshall(entry.getValue());
        plainText.rewind();
        ByteBuffer cipherText;
        if (encryptionKey instanceof DelegatedKey) {
          DelegatedKey dk = (DelegatedKey) encryptionKey;
          cipherText = ByteBuffer.wrap(dk.encrypt(toByteArray(plainText), null, encryptionMode));
        } else {
          if (cipher == null) {
            blockSize = getBlockSize(encryptionMode);
            cipher = Cipher.getInstance(encryptionMode);
          }
          // Encryption format: <iv><ciphertext>
          // Note a unique iv is generated per attribute
          cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, Utils.getRng());
          cipherText = ByteBuffer.allocate(blockSize + cipher.getOutputSize(plainText.remaining()));
          cipherText.position(blockSize);
          cipher.doFinal(plainText, cipherText);
          cipherText.flip();
          final byte[] iv = cipher.getIV();
          if (iv.length != blockSize) {
            throw new IllegalStateException(
                String.format(
                    "Generated IV length (%d) not equal to block size (%d)", iv.length, blockSize));
          }
          cipherText.put(iv);
          cipherText.rewind();
        }
        // Replace the plaintext attribute value with the encrypted content
        entry.setValue(new AttributeValue().withB(cipherText));
      }
    }
  }