SIGN IN SIGN UP

Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.

0 0 74 Java
2021-11-15 13:15:43 +00:00
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#define AWS_DISABLE_DEPRECATION
#include <awsdoc/s3-encryption/s3_encryption_examples.h>
#include <aws/s3-encryption/S3EncryptionClient.h>
#include <aws/s3-encryption/CryptoConfiguration.h>
#include <aws/s3-encryption/materials/KMSEncryptionMaterials.h>
#include <aws/s3-encryption/materials/SimpleEncryptionMaterials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/CreateBucketRequest.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/core/client/ClientConfiguration.h>
#include <aws/core/utils/crypto/Cipher.h>
using namespace Aws::S3;
using namespace Aws::S3::Model;
using namespace Aws::S3Encryption;
using namespace Aws::S3Encryption::Materials;
static const char ALLOCATION_TAG[] = "s3-encryption-examples";
bool AwsDoc::S3Encryption::KMSWithContextEncryptionMaterialsExample(const char* bucket, const char* objectKey, const char* masterKeyId)
{
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = Aws::Region::US_EAST_1;
const auto kmsWithContextEncryptionMaterials = Aws::MakeShared<KMSWithContextEncryptionMaterials>(ALLOCATION_TAG, masterKeyId, clientConfig);
CryptoConfigurationV2 cryptoConfig(kmsWithContextEncryptionMaterials);
S3EncryptionClientV2 s3EncryptionClient(cryptoConfig, clientConfig);
Aws::String content = "Hello from KMSWithContextEncryptionMaterials";
auto contentStream = Aws::MakeShared<Aws::StringStream>("s3Encryption");
*contentStream << content;
// Put an encrypted object to S3
PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucket).WithKey(objectKey).SetBody(contentStream);
Aws::Map<Aws::String, Aws::String> kmsContextMap;
kmsContextMap.emplace("client", "aws-sdk-cpp");
kmsContextMap.emplace("version", "1.8.0");
auto putObjectOutcome = s3EncryptionClient.PutObject(putObjectRequest, kmsContextMap /* Or {} as an empty map */);
if (putObjectOutcome.IsSuccess()) {
std::cout << "Put object with KMSWithContextEncryptionMaterials succeeded" << std::endl;
} else {
std::cout << "Error while putting object with KMSWithContextEncryptionMaterials: \n"
<< putObjectOutcome.GetError() << std::endl;
return false;
}
// Get an encrypted object from S3
GetObjectRequest getRequest;
getRequest.WithBucket(bucket).WithKey(objectKey);
Aws::String decryptedContent;
auto getObjectOutcome = s3EncryptionClient.GetObject(getRequest);
if (getObjectOutcome.IsSuccess()) {
Aws::StringStream ss;
ss << getObjectOutcome.GetResult().GetBody().rdbuf();
decryptedContent = ss.str();
std::cout << "Successfully retrieved object with content: "
<< decryptedContent << std::endl;;
} else {
std::cout << "Error while getting object: \n"
<< getObjectOutcome.GetError() << std::endl;
return false;
}
return decryptedContent == content;
}
bool AwsDoc::S3Encryption::SimpleEncryptionMaterialsWithGCMAADExample(const char* bucket, const char* objectKey)
{
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = Aws::Region::US_EAST_1;
auto symmetricKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey();
const auto simpleEncryptionMaterialsWithGCMAAD = Aws::MakeShared<SimpleEncryptionMaterialsWithGCMAAD>(ALLOCATION_TAG, symmetricKey);
CryptoConfigurationV2 cryptoConfig(simpleEncryptionMaterialsWithGCMAAD);
S3EncryptionClientV2 s3EncryptionClient(cryptoConfig, clientConfig);
Aws::String content = "Hello from SimpleEncryptionMaterialsWithGCMAAD";
auto contentStream = Aws::MakeShared<Aws::StringStream>("s3Encryption");
*contentStream << content;
// Put an encrypted object to S3
PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucket).WithKey(objectKey).SetBody(contentStream);
// Has to specify an empty map here for SimpleEncryptionMaterialsWithGCMAAD.
auto putObjectOutcome = s3EncryptionClient.PutObject(putObjectRequest, {});
if (putObjectOutcome.IsSuccess()) {
std::cout << "Put object with SimpleEncryptionMaterialsWithGCMAAD succeeded" << std::endl;
} else {
std::cout << "Error while putting object with KMSWithContextEncryptionMaterials: \n"
<< putObjectOutcome.GetError() << std::endl;
return false;
}
//get an encrypted object from S3
GetObjectRequest getRequest;
getRequest.WithBucket(bucket).WithKey(objectKey);
Aws::String decryptedContent;
auto getObjectOutcome = s3EncryptionClient.GetObject(getRequest);
if (getObjectOutcome.IsSuccess()) {
Aws::StringStream ss;
ss << getObjectOutcome.GetResult().GetBody().rdbuf();
decryptedContent = ss.str();
std::cout << "Successfully retrieved object with content: "
<< decryptedContent << std::endl;
} else {
std::cout << "Error while getting object: \n"
<< getObjectOutcome.GetError() << std::endl;
return false;
}
return decryptedContent == content;
}
bool AwsDoc::S3Encryption::DecryptObjectsEncryptedWithLegacyEncryptionExample(const char* bucket, const char* objectKey)
{
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = Aws::Region::US_EAST_1;
auto symmetricKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey();
const auto simpleEncryptionMaterials = Aws::MakeShared<SimpleEncryptionMaterials>(ALLOCATION_TAG, symmetricKey);
CryptoConfiguration cryptoConfig(CryptoMode::ENCRYPTION_ONLY);
S3EncryptionClient s3EncryptionClient(simpleEncryptionMaterials, cryptoConfig, clientConfig);
Aws::String content = "Hello from DecryptObjectsEncryptedWithLegacyEncryption";
auto contentStream = Aws::MakeShared<Aws::StringStream>("s3Encryption");
*contentStream << content;
// Put an encrypted object to S3
PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucket).WithKey(objectKey).SetBody(contentStream);
// Has to specify an empty map here for SimpleEncryptionMaterialsWithGCMAAD.
auto putObjectOutcome = s3EncryptionClient.PutObject(putObjectRequest);
if (putObjectOutcome.IsSuccess()) {
std::cout << "Put object with SimpleEncryptionMaterials and EncryptionOnly crypto mode succeeded" << std::endl;
} else {
std::cout << "Error while putting object with SimpleEncryptionMaterials and EncryptionOnly crypto mode: \n"
<< putObjectOutcome.GetError() << std::endl;
return false;
}
const auto simpleEncryptionMaterialsWithGCMAAD = Aws::MakeShared<SimpleEncryptionMaterialsWithGCMAAD>(ALLOCATION_TAG, symmetricKey);
CryptoConfigurationV2 cryptoConfigV2(simpleEncryptionMaterialsWithGCMAAD);
// By default, SecurityProfile is V2 for CryptoConfigurationV2. You need to specify V2_AND_LEGACY explicitly.
// Otherwise S3EncryptionClientV2 is not able to decrypt objects encrypted with legacy (less secure) encryption.
cryptoConfigV2.SetSecurityProfile(SecurityProfile::V2_AND_LEGACY);
S3EncryptionClientV2 s3EncryptionClientV2(cryptoConfigV2, clientConfig);
//get an encrypted object from S3
GetObjectRequest getRequest;
getRequest.WithBucket(bucket).WithKey(objectKey);
Aws::String decryptedContent;
auto getObjectOutcome = s3EncryptionClientV2.GetObject(getRequest);
if (getObjectOutcome.IsSuccess()) {
Aws::StringStream ss;
ss << getObjectOutcome.GetResult().GetBody().rdbuf();
decryptedContent = ss.str();
std::cout << "Successfully retrieved object with content: "
<< decryptedContent << std::endl;
} else {
std::cout << "Error while getting object: \n"
<< getObjectOutcome.GetError() << std::endl;
return false;
}
return decryptedContent == content;
}
bool AwsDoc::S3Encryption::DecryptObjectsWithRangeExample(const char* bucket, const char* objectKey)
{
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = Aws::Region::US_EAST_1;
auto symmetricKey = Aws::Utils::Crypto::SymmetricCipher::GenerateKey();
const auto simpleEncryptionMaterialsWithGCMAAD = Aws::MakeShared<SimpleEncryptionMaterialsWithGCMAAD>(ALLOCATION_TAG, symmetricKey);
CryptoConfigurationV2 cryptoConfig(simpleEncryptionMaterialsWithGCMAAD);
// By default, RangeGetMode is DISABLED for CryptoConfigurationV2. You need to specify RangeGetMode::ALL explicitly.
// Otherwise S3EncryptionClientV2 is not able to decrypt objects with range.
cryptoConfig.SetUnAuthenticatedRangeGet(RangeGetMode::ALL);
S3EncryptionClientV2 s3EncryptionClient(cryptoConfig, clientConfig);
Aws::String content = "Hello from DecryptObjectsWithRange";
auto contentStream = Aws::MakeShared<Aws::StringStream>("s3Encryption");
*contentStream << content;
// Put an encrypted object to S3
PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucket).WithKey(objectKey).SetBody(contentStream);
// Has to specify an empty map here for SimpleEncryptionMaterialsWithGCMAAD.
auto putObjectOutcome = s3EncryptionClient.PutObject(putObjectRequest, {});
if (putObjectOutcome.IsSuccess()) {
std::cout << "Put object with SimpleEncryptionMaterialsWithGCMAAD succeeded" << std::endl;
} else {
std::cout << "Error while putting object with KMSWithContextEncryptionMaterials: \n"
<< putObjectOutcome.GetError() << std::endl;
return false;
}
//get an encrypted object from S3
GetObjectRequest getRequest;
getRequest.WithBucket(bucket).WithKey(objectKey).WithRange("bytes=11-24");
Aws::String decryptedContent;
auto getObjectOutcome = s3EncryptionClient.GetObject(getRequest);
if (getObjectOutcome.IsSuccess()) {
Aws::StringStream ss;
ss << getObjectOutcome.GetResult().GetBody().rdbuf();
decryptedContent = ss.str();
std::cout << "Successfully retrieved object with content range \"bytes=11-24\": "
<< decryptedContent << std::endl;
} else {
std::cout << "Error while getting object: \n"
<< getObjectOutcome.GetError() << std::endl;
return false;
}
return decryptedContent == content.substr(11, 24-11+1);
}
bool AwsDoc::S3Encryption::DecryptObjectsWithAnyCMKExample(const char* bucket, const char* objectKey, const char* masterKeyId)
{
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = Aws::Region::US_EAST_1;
const auto kmsWithContextEncryptionMaterials = Aws::MakeShared<KMSWithContextEncryptionMaterials>(ALLOCATION_TAG, masterKeyId, clientConfig);
CryptoConfigurationV2 cryptoConfig(kmsWithContextEncryptionMaterials);
S3EncryptionClientV2 s3EncryptionClient(cryptoConfig, clientConfig);
Aws::String content = "Hello from KMSWithContextEncryptionMaterials";
auto contentStream = Aws::MakeShared<Aws::StringStream>("s3Encryption");
*contentStream << content;
// Put an encrypted object to S3
PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucket).WithKey(objectKey).SetBody(contentStream);
auto putObjectOutcome = s3EncryptionClient.PutObject(putObjectRequest, {});
if (putObjectOutcome.IsSuccess()) {
std::cout << "Put object with KMSWithContextEncryptionMaterials succeeded" << std::endl;
} else {
std::cout << "Error while putting object with KMSWithContextEncryptionMaterials: \n"
<< putObjectOutcome.GetError() << std::endl;
return false;
}
const auto kmsWithContextEncryptionMaterialsWithAnyCMK = Aws::MakeShared<KMSWithContextEncryptionMaterials>(ALLOCATION_TAG, ""/* empty master key ID */, clientConfig);
kmsWithContextEncryptionMaterialsWithAnyCMK->SetKMSDecryptWithAnyCMK(true);
CryptoConfigurationV2 cryptoConfigWithAnyCMK(kmsWithContextEncryptionMaterialsWithAnyCMK);
S3EncryptionClientV2 s3DecryptionClient(cryptoConfigWithAnyCMK, clientConfig);
// Get an encrypted object from S3
GetObjectRequest getRequest;
getRequest.WithBucket(bucket).WithKey(objectKey);
Aws::String decryptedContent;
auto getObjectOutcome = s3DecryptionClient.GetObject(getRequest);
if (getObjectOutcome.IsSuccess()) {
Aws::StringStream ss;
ss << getObjectOutcome.GetResult().GetBody().rdbuf();
decryptedContent = ss.str();
std::cout << "Successfully retrieved object with any CMK with content: "
<< decryptedContent << std::endl;;
} else {
std::cout << "Error while getting object: \n"
<< getObjectOutcome.GetError() << std::endl;
return false;
}
return decryptedContent == content;
}
int main(int argc, char** argv)
{
if (argc != 4)
{
std::cout << "\n" <<
"To run this example, supply: \n"
"(1) The name (key) prefix of an S3 object. The actual object key name will be generated based on the prefix, for example \"<key-prefix>-kms-with-context-encryption-materials\".\n"
"(2) The bucket name that it's contained within.\n"
"(3) And the KMS master key ID used for KMS encryption materials.\n\n"
"Ex: run_s3Encryption my-key-prefix my-bucket 1234abcd-12ab-34cd-56ef-1234567890ab" << std::endl;
exit(1);
}
const char* OBJECT_KEY_PREFIX = argv[1];
const char* BUCKET = argv[2];
const char* MASTER_KEY_ID = argv[3];
Aws::SDKOptions options;
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
Aws::InitAPI(options);
{
// Create the specified bucket using vanilla S3 client first
Aws::Client::ClientConfiguration config;
config.region = Aws::Region::US_EAST_1;
S3Client s3Client(config);
CreateBucketRequest createBucketRequest;
createBucketRequest.SetBucket(BUCKET);
createBucketRequest.SetACL(BucketCannedACL::private_);
CreateBucketOutcome createBucketOutcome = s3Client.CreateBucket(createBucketRequest);
if (!createBucketOutcome.IsSuccess()) {
std::cout << "Bucket Creation failed: \n"
<< createBucketOutcome.GetError() << std::endl;
exit(-1);
} else {
std::cout << "Bucket Creation succeeded!\n" << std::endl;
}
Aws::String objectKey(OBJECT_KEY_PREFIX);
AwsDoc::S3Encryption::KMSWithContextEncryptionMaterialsExample(BUCKET, (objectKey + "-kms-with-context-encryption-materials").c_str(), MASTER_KEY_ID);
std::cout << std::endl;
AwsDoc::S3Encryption::SimpleEncryptionMaterialsWithGCMAADExample(BUCKET, (objectKey + "-simple-encryption-materials-with-gcm-aad").c_str());
std::cout << std::endl;
AwsDoc::S3Encryption::DecryptObjectsEncryptedWithLegacyEncryptionExample(BUCKET, (objectKey + "-decrypt-objects-encrypted-with-legacy-encryption").c_str());
std::cout << std::endl;
AwsDoc::S3Encryption::DecryptObjectsWithRangeExample(BUCKET, (objectKey + "-decrypt-objects-with-range").c_str());
std::cout << std::endl;
AwsDoc::S3Encryption::DecryptObjectsWithAnyCMKExample(BUCKET, (objectKey + "-decrypt-objects-with-any-cmk").c_str(), MASTER_KEY_ID);
}
Aws::ShutdownAPI(options);
return 0;
}