2012-01-05 12 views
6

Z jakiegoś powodu zmagam się z generacją sygnatur dla mojej polityki przesyłania Amazon S3. Przysięgam, że działałem w pewnym momencie, ale już nie. Każda pomoc byłaby bardzo cenna. Potrzebuję świeżego zestawu oczu.Podpisanie Polityki Amazon S3 w Javie

W przypadku porównania z wynikiem z Amazon S3 Signature Tester, jestem , a nie uzyskiwanie tego samego podpisu. Jednak kiedy bezpośrednio używam podpisu wychodzącego z tego narzędzia, wszystko działa dobrze. Tak więc problem jest zdecydowanie w moim procesie podpisywania. Ponadto, "Dekodowany łańcuch szesnastkowy" pochodzący z tego narzędzia jest identyczny z moją sygnaturą wejściową, która jest podpisywana.

Docs AWS powiedzieć the process for constructing a policy signature powinno iść tak:

  1. Koduje polityka użyciu UTF-8.
  2. Zakoduj te bajty UTF-8, używając Base64.
  3. Podpowiedz zasady za pomocą tajnego klucza dostępu za pomocą HMAC SHA-1.
  4. Zakoduj sygnaturę SHA-1 za pomocą Base64.

wydaje się dość prosta. Jedynym miejscem na dwuznaczność może być # 3. Dokumenty AWS pokazują a sample snippet for generating HMAC-SHA1 i jest to zgodne z other Java cryptography examples, które widziałem.

Używam v1.6 Apache Commons realizacji Base64. Mój kod podpisanie zasadniczo wygląda następująco:

import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.binary.Base64; 

/* ... */ 

private static final String UTF8 = "UTF-8"; 
private static final String HMACSHA1 = "HmacSHA1"; 

public static String sign(String secret, String data) { 
    byte[] dataBytes = data.getBytes(UTF8); 
    byte[] secretBytes = secret.getBytes(UTF8); 

    SecretKeySpec signingKey = new SecretKeySpec(secretBytes, HMACSHA1); 

    Mac mac = Mac.getInstance(HMACSHA1); 
    mac.init(signingKey); 
    byte[] signature = mac.doFinal(dataBytes); 

    return Base64.encodeBase64String(signature); 
} 

I wtedy mój wykorzystania tego podpisania wygląda następująco:

String signature = sign(
    /* AWS Secret Access Key copied directly out of the AWS Console */, 
    /* policy properly serialized as JSON */); 

Odpowiedz

5

Dobra, znalazłem go. Podobno dziś skutecznie pomijam krok 2. Zrobiłem kodować polityki JSON jako base64, ale wtedy ja bezpośrednio podpisaniu ciąg JSON nie ciąg Base64.

Krok 3 powinien prawdopodobnie zostać zmieniony na "Podpisanie zasady Base64 za pomocą tajnego klucza dostępu przy użyciu HMAC SHA-1."

Chyba będę to zostawić w przypadku gdy ktoś inny spotyka podobny problem.

-1
String policy_document = 
     "{\"expiration\": \"2009-01-01T00:00:00Z\"," + 
     "\"conditions\": [" + 
      "{\"bucket\": \"s3-bucket\"}," + 
      "[\"starts-with\", \"$key\", \"uploads/\"]," + 
      "{\"acl\": \"private\"}," + 
      "{\"success_action_redirect\": \"http://localhost/\"}," + 
      "[\"starts-with\", \"$Content-Type\", \"\"]," + 
      "[\"content-length-range\", 0, 1048576]" + 
     "]" + 
     "}"; 

    // Calculate policy and signature values from the given policy document and AWS credentials. 
    String policy = new String(
     Base64.encodeBase64(policy_document.getBytes("UTF-8")), "ASCII"); 

    Mac hmac = Mac.getInstance("HmacSHA1"); 
    hmac.init(new SecretKeySpec(
     aws_secret_key.getBytes("UTF-8"), "HmacSHA1")); 
    String signature = new String(
     Base64.encodeBase64(hmac.doFinal(policy.getBytes("UTF-8"))), "ASCII"); 
3

Teraz, procedura ta jest oficjalnie obsługiwane. http://aws.amazon.com/articles/1434

import sun.misc.BASE64Encoder; 
import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 

String policy = (new BASE64Encoder()).encode(
policy_document.getBytes("UTF-8")).replaceAll("\n","").replaceAll("\r",""); 

Mac hmac = Mac.getInstance("HmacSHA1"); 
hmac.init(new SecretKeySpec(
aws_secret_key.getBytes("UTF-8"), "HmacSHA1")); 
String signature = (new BASE64Encoder()).encode(
hmac.doFinal(policy.getBytes("UTF-8"))) 
.replaceAll("\n", ""); 

* Strzeż realizację okna dla tego przykładu jako jakiegoś znalezionego problemu z uwagami słupka i rozwiązanie problemu było również przewidziane tam.

Wynik może zostać zweryfikowana przez ten http://s3.amazonaws.com/doc/s3-example-code/post/post_sample.html

Jednak niektóre powiedział to „org.apache.commons.codec.binary.Base64” to lepiej z tego powodu. http://www.asgarli.net/2011/03/replacing-sunmiscbase64encoder-and.html