没有使用.net S3获取客户端加密

时间:2014-12-18 05:58:05

标签: c# encryption amazon-s3

我已经开始使用AWS的sdk for S3,一切都说我应该为上传获得客户端加密,但是当我用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);

1 个答案:

答案 0 :(得分:2)

几个月前我遇到了同样的问题,但是通过引入SymmetricAlgorithm和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(),后者又在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或别名来解密信封密钥,仅加密信封密钥。

此答案也发布在Amazon Web Services Developer Forums