AWS SDK for .NET V3 已结束支持。
我们建议您迁移到 AWS SDK for .NET V4。有关如何迁移的更多详细信息和信息,请参阅我们的终止支持公告
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在中使用 AWS KMS 密钥进行 Amazon S3 加密 AWS SDK for .NET
此示例向您展示如何使用 AWS Key Management Service 密钥加密 Amazon S3 对象。该应用程序创建客户主密钥 (CMK),并使用它来创建用于客户端加密的 A mazonS3 EncryptionClient V2
警告
名为AmazonS3EncryptionClient的类似类已被弃用,其安全性不如 AmazonS3EncryptionClientV2 类。要迁移使用 AmazonS3EncryptionClient 的现有代码,请参阅S3 加密客户端迁移(从 V1 到 V2)。
创建加密材料
以下代码片段创建了一个包含 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类中,从而在客户端中自动透明地进行加密和解密。
-
使用 AWS KMS 密钥作为主密钥的一个好处是,您无需存储和管理自己的主密钥;这是通过完成的 AWS。第二个优点是,的
AmazonS3EncryptionClientV2AWS SDK for .NET 类可以与的AmazonS3EncryptionClientV2类互操作。 AWS SDK for Java这意味着您可以使用加密 AWS SDK for Java 并使用解密 AWS SDK for .NET,反之亦然。注意
的
AmazonS3EncryptionClientV2类仅在元数据模式下运行时 AWS SDK for .NET 支持 KMS 主密钥。的AmazonS3EncryptionClientV2类的指令文件模式与的AmazonS3EncryptionClientV2类 AWS SDK for .NET 不兼容 AWS SDK for Java。
-
有关该
AmazonS3EncryptionClientV2类的客户端加密以及信封加密的工作原理的更多信息,请参阅使用AWS SDK for .NET 和 Amazon S3 进行客户端数据加密。