如何在Ruby中使用S3 SSE C(客户端提供密钥的服务器端加密)

如何在Ruby中使用S3 SSE C(客户端提供密钥的服务器端加密),ruby,amazon-web-services,amazon-s3,encryption,aes,Ruby,Amazon Web Services,Amazon S3,Encryption,Aes,我正在尝试将一个文件上载到S3,并使用。我可以在不使用SSE-C选项的情况下上传,但当我提供SSE_customer_密钥选项时,会出现以下错误: ArgumentError:标头x-amz-server-side-encryption-customer-key具有字段值“QKEXM0JGRTNDMUYRDRCQZA5NJAWNEQ2MJRBNKEXMDYWQZBGQJCXODJM0\NNMUE2MTNENDRCOCTXRJA2QZK1MG=”,这不能包括CR/LF 我不确定问题出在生成的密钥还

我正在尝试将一个文件上载到S3,并使用。我可以在不使用SSE-C选项的情况下上传,但当我提供SSE_customer_密钥选项时,会出现以下错误:

ArgumentError:标头x-amz-server-side-encryption-customer-key具有字段值“QKEXM0JGRTNDMUYRDRCQZA5NJAWNEQ2MJRBNKEXMDYWQZBGQJCXODJM0\NNMUE2MTNENDRCOCTXRJA2QZK1MG=”,这不能包括CR/LF

我不确定问题出在生成的密钥还是编码上。我在这里使用了不同的选项,但是AWS文档不是很清楚。在通用SSE-C文档中,它指出您需要提供x-amz服务器端​-加密​-客户密钥标题,描述如下:

使用此标头提供256位base64编码的加密密钥 供AmazonS3用于加密或解密数据

但是,如果我看一下Ruby SDK文档中关于这3个选项的描述,就会发现它们略有不同

  • :sse_customer_algorithm(字符串)-指定加密对象时要使用的算法(例如
  • :sse_customer_key(String)-指定客户提供的加密密钥,供Amazon S3在中使用
  • :sse_customer_key_md5(字符串)-根据RFC指定加密密钥的128位md5摘要
(我没有抄错,AWS文档实际上是这样写的)

因此SDK文档使您看起来像是提供了原始的sse_customer_密钥,并且它将代表您对其进行base64编码(这对我来说很有意义)

因此,现在我正在构建如下选项:

  sse_customer_algorithm: :AES256,
  sse_customer_key: sse_customer_key,
  sse_customer_key_md5: Digest::MD5.hexdigest(sse_customer_key)
我以前尝试过执行
Base64.encode64(sse_customer_key)
,但这给了我一个不同的错误:

Aws::S3::Errors::InvalidArgument:密钥对于 指定算法

我不确定是生成的密钥不正确,还是提供的密钥不正确(或者是完全不同的问题)

这就是我生成密钥的方式:

require "openssl"
OpenSSL::Cipher.new("AES-256-CBC").random_key

哦,您是否注意到您的密钥包含“\n”?这很可能就是您得到CR/LF错误的原因:
qkexm0jgrtndmuyrdqza5njawnewq2mjrbnkexmdywqzbgqjcxodjm0(\n)nMUE2MTNENDRCOTcxRjA2Qzk1Mg=

正如同事在评论中提到的,这是一个选项,因为它符合RFC 2045

顺便说一下,我从这里了解到:


希望有帮助!:)

首先,请确保您使用的是来自的最新版本的SDK(2.2.2.2)

因此,据我所知,在生成预签名的URL时,我们必须指定SSECustomerMethod,并且在使用URL时,“x-amz-server-side-encryption-customer-key”头与客户密钥一起设置,您还需要设置“x-amz-server-side-encryption-customer-algorithm”头


Base64.strict\u encode64(关键)
也许吧?我还不能100%相信这是答案。如果我这样做了,我会在这里更新!
var getPresignedUrlRequest = new GetPreSignedUrlRequest
{
    BucketName = bucketName,
    Key = "EncryptedObject",
    SSECustomerMethod= SSECustomerMethod.AES256,
    Expires = DateTime.Now.AddMinutes(5)
};
var url = AWSClients.S3.GetPreSignedURL(getPresignedUrlRequest);
var webRequest = HttpWebRequest.Create(url);
webRequest.Headers.Add("x-amz-server-side-encryption-customer-algorithm", "AES256");
webRequest.Headers.Add("x-amz-server-side-encryption-customer-key", base64Key);

using (var response = webRequest.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
    var contents = reader.ReadToEnd();
}