我已经开始使用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);
答案 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或别名来解密信封密钥,仅加密信封密钥。