无法使用 .net S3 获取客户端加密

本文关键字:获取 客户端 加密 S3 net | 更新日期: 2023-09-27 18:34:30

我已经开始使用 AWS for S3 的 sdk,一切都说我应该为上传获得客户端加密,但是当我使用 S3 浏览器检查它时,它只显示服务器端加密,我做错了什么?

我正在使用亚马逊的加密密钥服务,用户拥有使用这些密钥进行加密的全部权限。

谢谢!

static string bucketName = "mybucket";
static EncryptionMaterials encryptionMaterials = new EncryptionMaterials(RSA.Create());
static AmazonS3EncryptionClient client = new AmazonS3EncryptionClient(Amazon.RegionEndpoint.USWest2, encryptionMaterials);
static void Main(string[] args)
{
     using (client)
     {
         try
         {
             PutObjectRequest putRequest1 = new PutObjectRequest
             {
                 BucketName = bucketName,
                 FilePath = @"C:'abc'def.pdf",
                 Key = "def.pdf",
                 ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS
             };
             client.PutObject(putRequest1);

无法使用 .net S3 获取客户端加密

几个月

前我遇到了同样的问题,但这是通过引入对称算法和ICryptoTransform实现来支持KMS来解决的。它们使用 KMS 服务和指定的 CMK 透明地加密和解密信封密钥。

public class KMSAlgorithm : SymmetricAlgorithm
{
    private IAmazonKeyManagementService _client;
    private string _keyId;
    public KMSAlgorithm(IAmazonKeyManagementService client)
    {
        this._client = client;
    }
    public KMSAlgorithm(IAmazonKeyManagementService client, string keyId)
        : this(client)
    {
        this._keyId = keyId;
    }
    public override ICryptoTransform CreateDecryptor()
    {
        return new KMSCryptoTransform.Decryptor(_client);
    }
    public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
    {
        throw new NotImplementedException();
    }
    public override ICryptoTransform CreateEncryptor()
    {
        return new KMSCryptoTransform.Encryptor(_client, _keyId);
    }
    public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
    {
        throw new NotImplementedException();
    }
    public override void GenerateIV()
    {
        throw new NotImplementedException();
    }
    public override void GenerateKey()
    {
        throw new NotImplementedException();
    }
}
public abstract class KMSCryptoTransform : ICryptoTransform
{
    protected IAmazonKeyManagementService _client;
    protected string _keyId;
    public KMSCryptoTransform(IAmazonKeyManagementService client)
    {
        this._client = client;
    }
    public KMSCryptoTransform(IAmazonKeyManagementService client, string keyId)
        : this(client)
    {
        this._keyId = keyId;
    }
    public bool CanReuseTransform
    {
        get { return true; }
    }
    public bool CanTransformMultipleBlocks
    {
        get { return false; }
    }
    public int InputBlockSize
    {
        get { throw new NotImplementedException(); }
    }
    public int OutputBlockSize
    {
        get { throw new NotImplementedException(); }
    }
    public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
    {
        throw new NotImplementedException();
    }
    public abstract byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount);
    public void Dispose()
    {
    }
    public class Decryptor : KMSCryptoTransform
    {
        public Decryptor(IAmazonKeyManagementService client)
            : base(client) { }
        public override byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
        {
            return _client.Decrypt(new DecryptRequest()
            {
                CiphertextBlob = new MemoryStream(inputBuffer, inputOffset, inputCount))
            }).Plaintext.ToArray();
        }
    }
    public class Encryptor : KMSCryptoTransform
    {
        public Encryptor(IAmazonKeyManagementService client, string keyId)
            : base(client, keyId) { }
        public override byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
        {
            return _client.Encrypt(new EncryptRequest()
            {
                KeyId = _keyId,
                Plaintext = MemoryStream(inputBuffer, inputOffset, inputCount))
            }).CiphertextBlob.ToArray();
        }
    }
}

这个KMSAlgorithm被用来代替EncryptionMaterials构造函数中的Aes.Create((,而Aes.Create((又在AmazonS3EncryptionClient构造函数中使用。

var client = AWSClientFactory.CreateAmazonKeyManagementServiceClient();
using (var algorithm = new KMSAlgorithm(client, "CustomerMasterKeyIdOrAlias"))
{
    var materials = new EncryptionMaterials(algorithm);
    var s3client = new AmazonS3EncryptionClient(materials);
    s3client.PutObject(new PutObjectRequest()
    {
        BucketName = "YourBucketName",
        Key = "YourKeyName",
        InputStream = new MemoryStream(Encoding.Default.GetBytes("Secret Message")),
    });
}
using (var algorithm = new KMSAlgorithm(client))
{
    var materials = new EncryptionMaterials(algorithm);
    var s3client = new AmazonS3EncryptionClient(materials);
    var obj = s3client.GetObject(new GetObjectRequest()
    {
        BucketName = "YourBucketName",
        Key = "YourKeyName"
    });
}

请注意,无需显式指定 CMK ID 或别名即可解密信封密钥,只需加密信封密钥即可。

此答案也发布在亚马逊云科技开发人员论坛中。