本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在中使用 Amazon KMS 密钥进行 Amazon S3 加密 Amazon SDK for .NET
此示例向您展示如何使用 Amazon Key Management Service 密钥加密 Amazon S3 对象。该应用程序创建客户主密钥 (CMK),并使用它来创建用于客户端加密的 A mazonS3 EncryptionClient V2
警告
名为AmazonS3EncryptionClient
的类似类已被弃用,其安全性不如 AmazonS3EncryptionClientV2
类。要迁移使用 AmazonS3EncryptionClient
的现有代码,请参阅S3 加密客户端迁移。
创建加密材料
以下代码段创建了一个包含KMS密钥 ID 的EncryptionMaterials
对象。
本主题末尾的示例显示了此片段的使用情况。
// Create a customer master key (CMK) and store the result CreateKeyResponse createKeyResponse = await new AmazonKeyManagementServiceClient().CreateKeyAsync(new CreateKeyRequest()); var kmsEncryptionContext = new Dictionary<string, string>(); var kmsEncryptionMaterials = new EncryptionMaterialsV2( createKeyResponse.KeyMetadata.KeyId, KmsType.KmsContext, kmsEncryptionContext);
创建并加密 Amazon S3 对象
以下代码片段创建了一个使用先前创建的加密材料的 AmazonS3EncryptionClientV2
对象。然后,它使用客户端来创建和加密一个新的 Amazon S3 对象。
本主题末尾的示例显示了此片段的使用情况。
// // Method to create and encrypt an object in an S3 bucket static async Task<GetObjectResponse> CreateAndRetrieveObjectAsync( EncryptionMaterialsV2 materials, string bucketName, string fileName, string itemName) { // CryptoStorageMode.ObjectMetadata is required for KMS EncryptionMaterials var config = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy) { StorageMode = CryptoStorageMode.ObjectMetadata }; var s3EncClient = new AmazonS3EncryptionClientV2(config, materials); // Create, encrypt, and put the object await s3EncClient.PutObjectAsync(new PutObjectRequest { BucketName = bucketName, Key = itemName, ContentBody = File.ReadAllText(fileName) }); // Get, decrypt, and return the object return await s3EncClient.GetObjectAsync(new GetObjectRequest { BucketName = bucketName, Key = itemName }); }
完整代码
本部分显示了本示例的相关参考和完整代码。
NuGet 包裹:
编程元素:
using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Amazon.Extensions.S3.Encryption; using Amazon.Extensions.S3.Encryption.Primitives; using Amazon.S3.Model; using Amazon.KeyManagementService; using Amazon.KeyManagementService.Model; namespace KmsS3Encryption { // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class to store text in an encrypted S3 object. class Program { private const int MaxArgs = 3; public static async Task Main(string[] args) { // Parse the command line and show help if necessary var parsedArgs = CommandLine.Parse(args); if((parsedArgs.Count == 0) || (parsedArgs.Count > MaxArgs)) { PrintHelp(); return; } // Get the application arguments from the parsed list string bucketName = CommandLine.GetArgument(parsedArgs, null, "-b", "--bucket-name"); string fileName = CommandLine.GetArgument(parsedArgs, null, "-f", "--file-name"); string itemName = CommandLine.GetArgument(parsedArgs, null, "-i", "--item-name"); if(string.IsNullOrEmpty(bucketName) || (string.IsNullOrEmpty(fileName))) CommandLine.ErrorExit( "\nOne or more of the required arguments is missing or incorrect." + "\nRun the command with no arguments to see help."); if(!File.Exists(fileName)) CommandLine.ErrorExit($"\nThe given file {fileName} doesn't exist."); if(string.IsNullOrEmpty(itemName)) itemName = Path.GetFileName(fileName); // Create a customer master key (CMK) and store the result CreateKeyResponse createKeyResponse = await new AmazonKeyManagementServiceClient().CreateKeyAsync(new CreateKeyRequest()); var kmsEncryptionContext = new Dictionary<string, string>(); var kmsEncryptionMaterials = new EncryptionMaterialsV2( createKeyResponse.KeyMetadata.KeyId, KmsType.KmsContext, kmsEncryptionContext); // Create the object in the bucket, then display the content of the object var putObjectResponse = await CreateAndRetrieveObjectAsync(kmsEncryptionMaterials, bucketName, fileName, itemName); Stream stream = putObjectResponse.ResponseStream; StreamReader reader = new StreamReader(stream); Console.WriteLine(reader.ReadToEnd()); } // // Method to create and encrypt an object in an S3 bucket static async Task<GetObjectResponse> CreateAndRetrieveObjectAsync( EncryptionMaterialsV2 materials, string bucketName, string fileName, string itemName) { // CryptoStorageMode.ObjectMetadata is required for KMS EncryptionMaterials var config = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy) { StorageMode = CryptoStorageMode.ObjectMetadata }; var s3EncClient = new AmazonS3EncryptionClientV2(config, materials); // Create, encrypt, and put the object await s3EncClient.PutObjectAsync(new PutObjectRequest { BucketName = bucketName, Key = itemName, ContentBody = File.ReadAllText(fileName) }); // Get, decrypt, and return the object return await s3EncClient.GetObjectAsync(new GetObjectRequest { BucketName = bucketName, Key = itemName }); } // // Command-line help private static void PrintHelp() { Console.WriteLine( "\nUsage: KmsS3Encryption -b <bucket-name> -f <file-name> [-i <item-name>]" + "\n -b, --bucket-name: The name of an existing S3 bucket." + "\n -f, --file-name: The name of a text file with content to encrypt and store in S3." + "\n -i, --item-name: The name you want to use for the item." + "\n If item-name isn't given, file-name will be used."); } } // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class that represents a command line on the console or terminal. // (This is the same for all examples. When you have seen it once, you can ignore it.) static class CommandLine { // // Method to parse a command line of the form: "--key value" or "-k value". // // Parameters: // - args: The command-line arguments passed into the application by the system. // // Returns: // A Dictionary with string Keys and Values. // // If a key is found without a matching value, Dictionary.Value is set to the key // (including the dashes). // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN", // where "N" represents sequential numbers. public static Dictionary<string,string> Parse(string[] args) { var parsedArgs = new Dictionary<string,string>(); int i = 0, n = 0; while(i < args.Length) { // If the first argument in this iteration starts with a dash it's an option. if(args[i].StartsWith("-")) { var key = args[i++]; var value = key; // Check to see if there's a value that goes with this option? if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++]; parsedArgs.Add(key, value); } // If the first argument in this iteration doesn't start with a dash, it's a value else { parsedArgs.Add("--NoKey" + n.ToString(), args[i++]); n++; } } return parsedArgs; } // // Method to get an argument from the parsed command-line arguments // // Parameters: // - parsedArgs: The Dictionary object returned from the Parse() method (shown above). // - defaultValue: The default string to return if the specified key isn't in parsedArgs. // - keys: An array of keys to look for in parsedArgs. public static string GetArgument( Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys) { string retval = null; foreach(var key in keys) if(parsedArgs.TryGetValue(key, out retval)) break; return retval ?? defaultReturn; } // // Method to exit the application with an error. public static void ErrorExit(string msg, int code=1) { Console.WriteLine("\nError"); Console.WriteLine(msg); Environment.Exit(code); } } }
额外注意事项
-
您可以查看此示例的结果。为此,请前往 Amazon S3 控制台
并打开您提供给应用程序的桶。然后找到新对象,下载后在文本编辑器中打开该对象。
-
A mazonS3 EncryptionClient V2
类实现的接口与标准 AmazonS3Client
类相同。这样可以更轻松地将代码移植到AmazonS3EncryptionClientV2
类中,从而在客户端中自动透明地进行加密和解密。
-
使用 Amazon KMS 密钥作为主密钥的一个好处是,您无需存储和管理自己的主密钥;这是通过完成的 Amazon。第二个优点是,的
AmazonS3EncryptionClientV2
Amazon SDK for .NET 类可以与的AmazonS3EncryptionClientV2
类互操作。 Amazon SDK for Java这意味着您可以使用加密 Amazon SDK for Java 并使用解密 Amazon SDK for .NET,反之亦然。注意
的
AmazonS3EncryptionClientV2
类仅在元数据模式下运行时才 Amazon SDK for .NET 支持KMS主密钥。的AmazonS3EncryptionClientV2
类的指令文件模式与的AmazonS3EncryptionClientV2
类 Amazon SDK for .NET 不兼容 Amazon SDK for Java。
-
有关该
AmazonS3EncryptionClientV2
类的客户端加密以及信封加密的工作原理的更多信息,请参阅使用Amazon SDK for .NET 和 Amazon S3 进行客户端数据加密。