如何使用签名版本4

时间:2019-01-25 16:40:22

标签: c# amazon-s3 .net-core aws-sdk aws-kms

我正在使用AWSSDK.S3(3.3.31.11)在C#.NET Core 2.0 API控制器类中生成一个预签名的URL。客户端Angular应用程序将使用生成的URL将文件上传到使用SSE-KMS加密的S3存储桶。尽管S3Client报告SignatureMethod为“ HmacSHA256”,SignatureVersion为“ 4”,但是当我尝试使用预签名的URL上传文件时,我收到一条错误消息,指出“使用AWS KMS托管密钥指定服务器端加密的请求需要AWS Signature版本4。”

S3Client作为对控制器类的依赖项被注入。 .NET Core DI框架使用config.json文件中的配置设置来管理对象的实例化:

{
    ...
    "AWS": {
        "Profile": "default",
        "Region": "us-east-1"
    }
    ...
}

我正在使用curl测试预签名URL:

curl -H "Content-Type: application/pdf" -H "x-amz-server-side-encryption: aws:kms" -H "x-amz-server-side-encryption-aws-kms-key-id: {kms-key-id}" -k -T "filename.pdf" "https://mybucketname.s3.amazonaws.com/filename.pdf?AWSAccessKeyId={keyid}&Expires={expires}&x-amz-security-token={token}&Signature={signature}"

我发现,如果不包含“ Content-Type”标头,则会收到“ SignatureDoesNotMatch”错误代码,而不是“ InvalidArgument”错误。

在为S3存储桶使用默认AES-256加密时,此过程以前一直有效,只是在转换为SSE-KMS时遇到了此问题。

// Controller Class
private readonly IAmazonS3 _s3Client;

public MyController(IAmazonS3 s3Client)
{
    _s3Client = s3Client;
}

[HttpPost]
public async Task<IActionResult> GetPreSignedUrl([FromBody] FileInfoDto fileInfo)
{
    ...
    GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
    {
        BucketName = bucketName, 
        Key = fileInfo.name, 
        Verb = HttpVerb.PUT,
        ContentType = fileInfo.contentType, 
        Expires = DateTime.Now.AddMinutes(5),
        ServerSideEncryptionKeyManagementServiceKeyId = keyId, 
        ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS
    };

    try
    {
        url = _s3Client.GetPreSignedURL(request);
    }
    ...
}

// Startup Class
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddDefaultAWSOptions(_config.GetAWSOptions());
    services.AddAWSService<IAmazonS3>();
    ...
}

当使用curl和控制器方法生成的预签名URL上传文件时,我收到响应错误代码“ InvalidArgument”和消息“使用AWS KMS托管密钥指定服务器端加密的请求需要AWS Signature版本4。”但是,S3Client报告SignatureVersion为“ 4”。

为了使用签名版本4生成预签名的URL,我应该做些什么?

1 个答案:

答案 0 :(得分:1)

尽管s3Client将签名版本报告为“ 4”,但将以下行添加到ConfigureServices方法中即可解决该问题并导致生成符合签名版本4的预签名URL:

AWSConfigsS3.UseSignatureVersion4 = true;

生成的预签名URL如下:

https://mybucketname.s3.amazonaws.com/filename.pdf?X-Amz-Expires=1800&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={credential}/20190127/us-east-1/s3/aws4_request&X-Amz-Date={date}&X-Amz-SignedHeaders=content-type;host;x-amz-server-side-encryption&X-Amz-Signature={signature}