首页 > 解决方案 > .NET Core - AWS KMS - EncryptionMaterials 问题

问题描述

我一直在尝试使用 KMS 管理器在 S3 存储桶中加密和存储一些敏感信息。我找到了很多关于如何做到这一点的示例,最重要的是 AWS 文档中的示例(https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/kms-keys-s3 -加密.html )

using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;

using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Encryption;
using Amazon.KeyManagementService;
using Amazon.KeyManagementService.Model;

namespace S3Sample1
{
    class S3Sample
    {
        public static void Main(string[] args)
        {
            string kmsKeyID = null;
            using (var kmsClient = new AmazonKeyManagementServiceClient())
            {
                var response = kmsClient.CreateKey(new CreateKeyRequest());
                kmsKeyID = response.KeyMetadata.KeyId;

                var keyMetadata = response.KeyMetadata; // An object that contains information about the CMK created by this operation.
                var bucketName = "<s3bucket>";
                var objectKey = "key";

                var kmsEncryptionMaterials = new EncryptionMaterials(kmsKeyID);
                // CryptoStorageMode.ObjectMetadata is required for KMS EncryptionMaterials
                var config = new AmazonS3CryptoConfiguration()
                {
                    StorageMode = CryptoStorageMode.ObjectMetadata
                };

                using (var s3Client = new AmazonS3EncryptionClient(config, kmsEncryptionMaterials))
                {
                    // encrypt and put object
                    var putRequest = new PutObjectRequest
                    {
                        BucketName = bucketName,
                        Key = objectKey,
                        ContentBody = "object content"
                    };
                    s3Client.PutObject(putRequest);

                    // get object and decrypt
                    var getRequest = new GetObjectRequest
                    {
                        BucketName = bucketName,
                        Key = objectKey
                    };

                    using (var getResponse = s3Client.GetObject(getRequest))
                    using (var stream = getResponse.ResponseStream)
                    using (var reader = new StreamReader(stream))
                    {
                        Console.WriteLine(reader.ReadToEnd());
                    }
                }
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }

    }

}

即使我使用完整框架(要在 .NET Core 中使用上面的示例,我必须根据他们的文档使所有 aws 调用异步)版本,此代码也不起作用,因为

var kmsEncryptionMaterials = new EncryptionMaterials(kmsKeyID);

不接受字符串,但可以接受 AsymmetricKey 或 SymmetricKey 对象。我绕过它

var kmsEncryptionMaterials = new EncryptionMaterials(RSA.Create())

显然这将是每个会话的密钥,所以我实际上找到了这篇文章https://aws.amazon.com/blogs/developer/client-side-data-encryption-with-aws-sdk-for-net-and-amazon -s3/,它基本上详细说明了如何重用一个似乎真的过时的密钥(创建于 2013 年),并且在我看来,我的用法与我最初想将 KMS 用作我们所有人的实际身份验证/授权提供程序的用法不符aws 生态系统中的盒子,然后访问包含密钥的 S3 存储桶。

我错过了什么吗?为什么 AWS 示例中有一个字符串?

我正在使用 AWS SDK .NET Core 的最新包:

标签: amazon-web-servicesamazon-s3asp.net-coreaws-sdkaws-kms

解决方案


在遇到这个问题将近一天后,我意识到问题与 Amazon.S3.Encryption dll 的多个目标有关。

我发现了一个 github 项目,该项目的示例正确地针对 .net 核心 ( https://github.com/priyalwalpita/awssdk_dotnetcore ) 工作,从他们那里很清楚问题出在我的缓存 dll 上。

我还对 csproj 中的 ItemGroups 进行了三次检查,并确保它们是正确的

  <ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.3.24.4" />
<PackageReference Include="AWSSDK.KeyManagementService" Version="3.3.6" />
<PackageReference Include="AWSSDK.S3" Version="3.3.20" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
  </ItemGroup>

希望这可能会在将来对某人有所帮助


推荐阅读