Java中PresignedURL的SignatureDoesNotMatch

Posted

技术标签:

【中文标题】Java中PresignedURL的SignatureDoesNotMatch【英文标题】:SignatureDoesNotMatch For PresignedURL in java 【发布时间】:2019-07-19 15:03:28 【问题描述】:
public S3PresignedURLServiceImpl() 
        amazonS3Client = AmazonS3ClientBuilder
                .standard()
                .withCredentials(new DefaultAWSCredentialsProviderChain())
                .withRegion(S3PresignedURLConstants.DEFAULT_REGION)
                .build();
    

[在本地它正在工作,但是当 lambda 部署在控制台上时,

SignatureDoesNotMatch 我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。

try 
    // Set the pre-signed URL to expire after specified time.
    java.util.Date expiration = new java.util.Date();
    long expTimeMillis = expiration.getTime();
    if(data.getExpiryTime() > 0) 
        expTimeMillis += 1000 * 60 * data.getExpiryTime();
     else 
        expTimeMillis += 100 * 60 * 60 * 6;
    
    expiration.setTime(expTimeMillis);
    HttpMethod httpMethod = data.isUpload()?HttpMethod.PUT:HttpMethod.GET;

    Logger.logInfo("Generating pre-signed URL.",REPORTER);
    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(data.getBucketName(), data.getFilePath())
            .withMethod(httpMethod)
            .withExpiration(expiration);
    if(!data.isUpload())
        generatePresignedUrlRequest.withVersionId(data.getVersionId());
    else generatePresignedUrlRequest.withContentType(data.getContentType());

    url = amazonS3Client.generatePresignedUrl(generatePresignedUrlRequest);
    responseData.setPreSignedUrl(url.toString());

catch(Exception e) 
    throw new S3PresignedURLException(e.getMessage(), e);

【问题讨论】:

我们应该首先缩小问题范围:既然这段代码既可以上传又可以下载,那么哪一个不起作用?此外,您是说 Lambda 控制台中存在错误......但您显示的代码只是 generating URL - 实际上并未尝试使用它。什么时候出现这个错误? 我只上传presignedUrl。这里 lambda 附加到 api gateway 。我在我的角度应用程序中使用这个 presign url 将文件上传到 s3。我尝试使用签名 URL 上传它返回 403 错误代码消息“SignatureDoesNotMatch 我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。”如果我运行我的 lambda 本地机器,它会返回 signedUrl 我可以使用这个本地生成的签名 url 上传文件。 【参考方案1】:

请检查库org.apache.httpcomponents:httpclient 的版本,如果是4.5.74.5.8,请尝试降级到4.5.6,因为AWS SDK S3 存在问题。更多详情请关注Amazon S3 Signature Does Not Match - AWS SDK Java和org.apache.httpcomponents:httpclient:4.5.7 breaks fetching S3 objects。

【讨论】:

【参考方案2】:

我们在向 AWS 报告工单时收到的解决方案,因为所有方法都失败了。场景是我们为 S3 存储桶启用了自定义 AWS KMS 加密,但是在使用 GeneratePresignedUrlRequest api 时,我们试图将“kms 密钥”与我们的请求一起发送。 AWS 说,我们不必发送 KMS 密钥,而是在不从客户端加密的情况下发送。当我说未加密时,并不完全是这样,它已经以加密形式出现,当我们使用“AWSS3V4SinerType”签名时,它正在签署一个已经加密的文件。希望这是有道理的。

【讨论】:

以上是关于Java中PresignedURL的SignatureDoesNotMatch的主要内容,如果未能解决你的问题,请参考以下文章

XML签名

Android 中 Amazon S3 预签名 URL 的改进

解压 Python 的类型注解

币安 API 密钥

node.js踩坑

S3签名的网址不适用于ajax