如何将 S3 SSE C(使用客户端提供的密钥的服务器端加密)与 Ruby 一起使用
How to use S3 SSE C (Server Side Encryption with Client Provided Keys) with Ruby
我正在尝试将文件上传到 S3 并使用 SSE-C encryption options 对其进行加密。我可以在没有 SSE-C 选项的情况下上传,但是当我提供 sse_customer_key 选项时,我收到以下错误:
ArgumentError: header x-amz-server-side-encryption-customer-key has field value "QkExM0JGRTNDMUUyRDRCQzA5NjAwNEQ2MjRBNkExMDYwQzBGQjcxODJDMjM0\nnMUE2MTNENDRCOTcxRjA2Qzk1Mg=", this cannot include CR/LF
我不确定问题出在我生成的密钥上还是编码上。我在这里尝试过不同的选项,但 AWS 文档不是很清楚。在一般的 SSE-C 文档中,它说您需要提供一个 x-amz-server-side -encryption -customer-key header,它被描述像这样:
Use this header to provide the 256-bit, base64-encoded encryption key
for Amazon S3 to use to encrypt or decrypt your data.
但是,如果我查看 uploading a file 的 Ruby SDK 文档,这 3 个选项的描述略有不同
- :sse_customer_algorithm(字符串)— 指定加密 object 时使用的算法(例如,
- :sse_customer_key(字符串)— 指定 Amazon S3 在
中使用的 customer-provided 加密密钥
- :sse_customer_key_md5 (String) — 根据 RFC
指定加密密钥的 128 位 MD5 摘要
(我没有抄错,AWS 文档字面意思就是half-written)
所以 SDK 文档看起来像是您提供了原始 sse_customer_key 并且它会代表您对其进行 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: The secret key was invalid for the
specified algorithm
我不确定是我生成的密钥不正确还是我提供的密钥不正确(或者这完全是另一个问题)。
这就是我生成密钥的方式:
require "openssl"
OpenSSL::Cipher.new("AES-256-CBC").random_key
哦,你有没有注意到你的密钥包含'\n'?这很可能就是您收到 CR/LF 错误的原因:
QkExM0JGRTNDMUUyRDRCQzA5NjAwNEQ2MjRBNkExMDYwQzBGQjcxODJDMjM0(\n)nMUE2MTNENDRCOTcxRjA2Qzk1Mg=
正如同事在评论中提到的,strict_encode64 是一个选项,因为它符合 RFC 2045。
顺便说一句,我从这里得到了这个见解:https://bugs.ruby-lang.org/issues/14664
希望对您有所帮助! :)
首先,请确保您使用的是 here
的最新版本 SDK (2.2.2.2)
因此,据我了解,当我们生成预签名的 URL 时,我们必须指定 SSECustomerMethod,并且在使用 URL 时,设置 "x-amz-server-side-encryption-customer-key" header使用客户密钥,您还需要设置 "x-amz-server-side-encryption-customer-algorithm" header.
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();
}
我正在尝试将文件上传到 S3 并使用 SSE-C encryption options 对其进行加密。我可以在没有 SSE-C 选项的情况下上传,但是当我提供 sse_customer_key 选项时,我收到以下错误:
ArgumentError: header x-amz-server-side-encryption-customer-key has field value "QkExM0JGRTNDMUUyRDRCQzA5NjAwNEQ2MjRBNkExMDYwQzBGQjcxODJDMjM0\nnMUE2MTNENDRCOTcxRjA2Qzk1Mg=", this cannot include CR/LF
我不确定问题出在我生成的密钥上还是编码上。我在这里尝试过不同的选项,但 AWS 文档不是很清楚。在一般的 SSE-C 文档中,它说您需要提供一个 x-amz-server-side -encryption -customer-key header,它被描述像这样:
Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data.
但是,如果我查看 uploading a file 的 Ruby SDK 文档,这 3 个选项的描述略有不同
- :sse_customer_algorithm(字符串)— 指定加密 object 时使用的算法(例如,
- :sse_customer_key(字符串)— 指定 Amazon S3 在 中使用的 customer-provided 加密密钥
- :sse_customer_key_md5 (String) — 根据 RFC 指定加密密钥的 128 位 MD5 摘要
(我没有抄错,AWS 文档字面意思就是half-written)
所以 SDK 文档看起来像是您提供了原始 sse_customer_key 并且它会代表您对其进行 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: The secret key was invalid for the specified algorithm
我不确定是我生成的密钥不正确还是我提供的密钥不正确(或者这完全是另一个问题)。
这就是我生成密钥的方式:
require "openssl"
OpenSSL::Cipher.new("AES-256-CBC").random_key
哦,你有没有注意到你的密钥包含'\n'?这很可能就是您收到 CR/LF 错误的原因:
QkExM0JGRTNDMUUyRDRCQzA5NjAwNEQ2MjRBNkExMDYwQzBGQjcxODJDMjM0(\n)nMUE2MTNENDRCOTcxRjA2Qzk1Mg=
正如同事在评论中提到的,strict_encode64 是一个选项,因为它符合 RFC 2045。
顺便说一句,我从这里得到了这个见解:https://bugs.ruby-lang.org/issues/14664
希望对您有所帮助! :)
首先,请确保您使用的是 here
的最新版本 SDK (2.2.2.2)因此,据我了解,当我们生成预签名的 URL 时,我们必须指定 SSECustomerMethod,并且在使用 URL 时,设置 "x-amz-server-side-encryption-customer-key" header使用客户密钥,您还需要设置 "x-amz-server-side-encryption-customer-algorithm" header.
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();
}