如何从 Java 在 AWS 中生成签名 [英] How to generate Signature in AWS from Java

查看:28
本文介绍了如何从 Java 在 AWS 中生成签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从 REST 客户端调用 API 端点时,我遇到了与签名相关的错误.

When I invoke API endpoints from REST client, I got error by concerning with Signature.

请求:

主机:https://xxx.execute-api.ap-southeast-1.amazonaws.com/latest/api/name

授权:AWS4-HMAC-SHA256 Credential={AWSKEY}/20160314/ap-southeast-1/execute-api/aws4_request,SignedHeaders=host;range;x-amz-date,Signature={signature}

Authorization: AWS4-HMAC-SHA256 Credential={AWSKEY}/20160314/ap-southeast-1/execute-api/aws4_request,SignedHeaders=host;range;x-amz-date,Signature={signature}

X-Amz-Date:20160314T102915Z

X-Amz-Date: 20160314T102915Z

回复:

{
"message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details. The Canonical String for this request should have been 'xxx' "
}

从 Java 代码中,我遵循 AWS 参考如何生成签名.

From Java code, I followed AWS reference of how to generate Signature.

    String secretKey = "{mysecretkey}";
    String dateStamp = "20160314";
    String regionName = "ap-southeast-1";
    String serviceName = "execute-api";

    byte[] signature = getSignatureKey(secretKey, dateStamp, regionName, serviceName);
    System.out.println("Signature : " + Hex.encodeHexString(signature));

    static byte[] HmacSHA256(String data, byte[] key) throws Exception  {
         String algorithm="HmacSHA256";
         Mac mac = Mac.getInstance(algorithm);
         mac.init(new SecretKeySpec(key, algorithm));
         return mac.doFinal(data.getBytes("UTF8"));
    }

    static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName) throws Exception  {
         byte[] kSecret = ("AWS4" + key).getBytes("UTF8");
         byte[] kDate    = HmacSHA256(dateStamp, kSecret);
         byte[] kRegion  = HmacSHA256(regionName, kDate);
         byte[] kService = HmacSHA256(serviceName, kRegion);
         byte[] kSigning = HmacSHA256("aws4_request", kService);
         return kSigning;
    }

我可以知道我在生成签名时做错了什么吗?

May I know what I was wrong while generating Signature?

参考如何生成签名:http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-java

推荐答案

您可以使用来自 aws-java-sdk-core 的类:https://github.com/aws/aws-sdk-java/tree/master/aws-java-sdk-core

You can use classes from aws-java-sdk-core: https://github.com/aws/aws-sdk-java/tree/master/aws-java-sdk-core

更具体地说,Request、Aws4Signer 和其他一些:

More specifically, Request, Aws4Signer and a few other ones:

//Instantiate the request
Request<Void> request = new DefaultRequest<Void>("es"); //Request to ElasticSearch
request.setHttpMethod(HttpMethodName.GET);
request.setEndpoint(URI.create("http://..."));

//Sign it...
AWS4Signer signer = new AWS4Signer();
signer.setRegionName("...");
signer.setServiceName(request.getServiceName());
signer.sign(request, new AwsCredentialsFromSystem());

//Execute it and get the response...
Response<String> rsp = new AmazonHttpClient(new ClientConfiguration())
    .requestExecutionBuilder()
    .executionContext(new ExecutionContext(true))
    .request(request)
    .errorResponseHandler(new SimpleAwsErrorHandler())
    .execute(new SimpleResponseHandler<String>());

如果你想要一个更简洁的设计,你可以使用装饰器模式来组合一些优雅的类并隐藏上面的混乱.这里的一个例子:http://www.amihaiemil.com/2017/02/18/decorators-with-tunnels.html

If you want a cleaner design, you can use the Decorator pattern to compose some elegant classes and hide the above mess. An example for that here: http://www.amihaiemil.com/2017/02/18/decorators-with-tunnels.html

这篇关于如何从 Java 在 AWS 中生成签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆