2016-03-14 18 views
5

RESTクライアントからAPIエンドポイントを呼び出すと、Signatureに関してエラーが発生しました。JavaからAWSでシグネチャを生成する方法

要求:

ホストhttps://xxx.execute-api.ap-southeast-1.amazonaws.com/latest/api/name

認可:AWS4-HMAC-SHA256資格= {AWSKEY}/20160314/AP-南東-1 /実行-API/aws4_request、SignedHeaders =ホスト、範囲、x-amz-date、署名= {signature}

x-amz-date:20160314 T102915Z

応答:Javaコードから

{ 
"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' " 
} 

は、私が署名を生成する方法のAWSの参照を行いました。

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; 
    } 

署名を生成する際に間違っていたことを知っていますか?署名を生成する方法

参考:http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-java

+0

ソリューションを見つけましたか? –

答えて

1

のコード例から、あなたが標準的な要求を作成し、http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html

の代わりにこれを実行するごとに署名される文字列でそれを含めていないように見えますの上自分でサードパーティ製のライブラリを使ってみましたか?

aws-v4-signer-javaは、AWS V4シグネチャの生成を容易にする軽量でゼロ依存性のライブラリです。

String contentSha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; 
HttpRequest request = new HttpRequest("GET", new URI("https://examplebucket.s3.amazonaws.com?max-keys=2&prefix=J")); 
String signature = Signer.builder() 
     .awsCredentials(new AwsCredentials(ACCESS_KEY, SECRET_KEY)) 
     .header("Host", "examplebucket.s3.amazonaws.com") 
     .header("x-amz-date", "20130524T000000Z") 
     .header("x-amz-content-sha256", contentSha256) 
     .buildS3(request, contentSha256) 
     .getSignature(); 

免責事項:私は図書館の著者です。

+0

Hiya Lucas、S3に直接アップロードするフロントエンドクライアントにシグネチャを提供するバックエンドサーバー用にこのライブラリをテストしたのが不思議です。コンテンツのクライアント側のsha256を計算し、それを署名計算の一部としてサーバーに提出する必要がありますか? – charneykaye

3

あなたは、AWS-javaの-SDK-コアからのクラスを使用することができます。https://github.com/aws/aws-sdk-java/tree/master/aws-java-sdk-core

は具体的には、要求は、Aws4Signerおよびその他のいくつかのものは:あなたはクリーンなデザインをしたい場合は

//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

関連する問題