SecretKey envelopeSymmetricKey = encryptedUploadContext.getEnvelopeEncryptionKey();
byte[] iv = encryptedUploadContext.getNextInitializationVector();
CipherFactory cipherFactory = new CipherFactory(envelopeSymmetricKey, Cipher.ENCRYPT_MODE, iv, this.cryptoConfig.getCryptoProvider());
// Create encrypted input stream
ByteRangeCapturingInputStream encryptedInputStream = EncryptionUtils.getEncryptedInputStream(uploadPartRequest, cipherFactory);
uploadPartRequest.setInputStream(encryptedInputStream);
// The last part of the multipart upload will contain extra padding from the encryption process, which
// changes the
if (uploadPartRequest.isLastPart()) {
// We only change the size of the last part
long cryptoContentLength = EncryptionUtils.calculateCryptoContentLength(cipherFactory.createCipher(), uploadPartRequest);
if (cryptoContentLength > 0) uploadPartRequest.setPartSize(cryptoContentLength);
if (encryptedUploadContext.hasFinalPartBeenSeen()) {
throw new AmazonClientException("This part was specified as the last part in a multipart upload, but a previous part was already marked as the last part. " +
"Only the last part of the upload should be marked as the last part, otherwise it will cause the encrypted data to be corrupted.");
}
encryptedUploadContext.setHasFinalPartBeenSeen(true);
}
// Treat all encryption requests as input stream upload requests, not as file upload requests.
uploadPartRequest.setFile(null);
uploadPartRequest.setFileOffset(0);
UploadPartResult result = super.uploadPart(uploadPartRequest);
encryptedUploadContext.setNextInitializationVector(encryptedInputStream.getBlock());
return result;
}