使用 AWS KMS 键 Amazon S3 加密 适用于 .NET 的 AWS 开发工具包 - 适用于 .NET 的 AWS 开发工具包
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 AWS KMS 键 Amazon S3 加密 适用于 .NET 的 AWS 开发工具包

本示例向您展示了如何使用 AWS Key Management Service 要加密的密钥 Amazon S3 对象。应用程序创建客户主密钥(CMK),并使用它创建 AmazonS3EncryptionClientV2 客户端加密对象。应用程序使用该客户端在现有 Amazon S3 桶。然后解密对象并显示其内容。

警告

类似的类称为 AmazonS3EncryptionClient 被弃用,且安全性低于 AmazonS3EncryptionClientV2 类。迁移使用的现有代码 AmazonS3EncryptionClient,请参阅 S3加密客户端迁移.

创建加密材料

下面的代码段会创建一个 EncryptionMaterials 包含KMS密钥ID的对象。

示例 在本主题结束时 显示了正在使用的片段。

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

完成代码

本节显示此示例的相关参考和完整代码。

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 parameters from the parsed arguments string bucketName = CommandLine.GetParameter(parsedArgs, null, "-b", "--bucket-name"); string fileName = CommandLine.GetParameter(parsedArgs, null, "-f", "--file-name"); string itemName = CommandLine.GetParameter(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: "--param value" or "-p value". // If "param" is found without a matching "value", Dictionary.Value is an empty string. // If "value" is found without a matching "param", Dictionary.Key is "--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 = string.Empty; // Is there 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 a parameter from the parsed command-line arguments public static string GetParameter( Dictionary<string,string> parsedArgs, string def, params string[] keys) { string retval = null; foreach(var key in keys) if(parsedArgs.TryGetValue(key, out retval)) break; return retval ?? def; } // // Exit with an error. public static void ErrorExit(string msg, int code=1) { Console.WriteLine("\nError"); Console.WriteLine(msg); Environment.Exit(code); } } }

其他注意事项

  • 您可以检查此示例的结果。为此,请前往 Amazon S3 控制台 并打开您提供给应用程序的存储桶。然后找到新对象,下载它,并在文本编辑器中打开它。

  • AmazonS3EncryptionClientV2 类实现与标准相同的界面 AmazonS3Client 类。这样一来,代码就更容易传送到 AmazonS3EncryptionClientV2 以便加密和解密在客户端中自动且透明地进行。

  • 使用 AWS KMS 关键是,您不需要存储和管理自己的主密钥;这通过 AWS. 第二个优点是 AmazonS3EncryptionClientV2 类别 适用于 .NET 的 AWS 开发工具包 与 AmazonS3EncryptionClientV2 类别 AWS SDK for Java. 这意味着,您可以使用AWS SDK for Java加密,然后使用适用于 .NET 的 AWS 开发工具包解密,反之亦然。

    注意

    AmazonS3EncryptionClientV2 类别 适用于 .NET 的 AWS 开发工具包 仅在元数据模式下运行时支持KMS主密钥。的说明文件模式 AmazonS3EncryptionClientV2 类别 适用于 .NET 的 AWS 开发工具包 与 AmazonS3EncryptionClientV2 类别 AWS SDK for Java.