Frage

I'm having tremendous problems trying to upload a file to the Google Cloud Storage (GCS) using a form on a webpage hosted on a Google App Engine (GAE), GWT, using POST OBJECT and a policy document and signature.

The biggest problems of all; I don't get any feedback on what is wrong.

First of all. I am able to upload a file to the GCS if I use no Policy or Signature at all, so I'm assuming the error lies in the that part. See below for code.

//Is used to get the policy as base64 and the signature (and converted to base64)
public String[] getPolicyAndSignature(String policy)
{
    try
    {
       KeyStore keystore = KeyStore.getInstance("PKCS12");
       keystore.load(new FileInputStream(new File("my_test_app/mykey.p12")), "notasecret".toCharArray());
       PrivateKey privateKey = (PrivateKey)keystore.getKey("privatekey", "notasecret".toCharArray());

       Signature signature = Signature.getInstance("SHA256withRSA");
       signature.initSign(privateKey);

       //is this wrong, should it be just: (?)
       //signature.update(policy.getBytes())
       signature.update(Base64Utils.toBase64(policy.getBytes()).getBytes());

       byte[] signatureBytes = signature.sign();
       byte[] policyBytes = policy.getBytes();

       return new String[]{Base64Utils.toBase64(policyBytes), Base64Utils.toBase64(signatureBytes)};
    }
    catch(Exception e)
    {
       System.out.println("Error: " + e.getMessage());
    }
    return null;
}

This is the code that uses that function:

public TestUploader()
{
    VerticalPanel mainPanel = new VerticalPanel();
    final FormPanel formPanel = new FormPanel();
    formPanel.setWidget(mainPanel);

    FileUpload upload = new FileUpload();
    upload.setName("file");
    formPanel.setAction("http://sgacms.storage.googleapis.com");
    formPanel.setMethod(FormPanel.METHOD_POST);
    formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
    formPanel.getElement().setAttribute("accept-charset", "UTF-8");

    String keyString = "testing";
    String bucketString = "sgacms";
    Hidden key = new Hidden("key", keyString);
    Hidden bucket = new Hidden("bucket", bucketString);
    Hidden contentType = new Hidden("Content-Type", "image/jpeg");
    Hidden GoogleAccessID = new Hidden("GoogleAccessID", "517031602192-p8kn8m33vhmhg9horbif8mansmkilqle@developer.gserviceaccount.com");
    Hidden acl = new Hidden("acl", "bucket-owner-read");
    final Hidden policy = new Hidden("policy");
    final Hidden hiddenSignature = new Hidden("signature");

    String policyString =
        "{\"expiration\":\"2016-06-16T11:11:11Z\","+
            "\"conditions\":["+
                "[\"starts-with\",\"$key\",\"\"],"+
                "{\"acl\":\"bucket-owner-read\"},"+
                "{\"bucket\":\"sgacms\"},"+
                "[\"eq\",\"$Content-Type\",\"image/jpeg\"],"+
                "[\"content-length-range\",0,1000000]"+
            "]"+
        "}";

    String[] policyAndSignature = getPolicyAndSignature(policyString);
    policy.setValue(policyAndSignature[0]);
    hiddenSignature.setValue(policyAndSignature[1]);

    Button btn = new Button("Submit");

    mainPanel.add(btn); //submit
    mainPanel.add(key); //hidden
    mainPanel.add(bucket); //hidden
    mainPanel.add(contentType); //hidden
    mainPanel.add(GoogleAccessID); //hidden
    mainPanel.add(acl); //hidden
    mainPanel.add(policy);  //hidden
    mainPanel.add(hiddenSignature); //hidden
    mainPanel.add(upload); //file

    initWidget(formPanel);

    btn.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            formPanel.submit();
        }
    });
    formPanel.addSubmitCompleteHandler(new SubmitCompleteHandler() {
        @Override
        public void onSubmitComplete(SubmitCompleteEvent event) {
            log.severe("Submit results: " + event.getResults());
        }
    });
}

The submit results simply prints: null, when I fail. And since I never succeed it never prints anything else. If I on the other hand uses no policy and no signature (in other words making an anonymous upload) the submit results will be empty and the file will be uploaded successfully.

So I can't figure out what is wrong! Any help is appreciated! Thank you!

EDIT: So now I've finally been able to get an error response which says the following: "SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method"

War es hilfreich?

Lösung

Okay so I've found the answer to my problem.

I'm a bit pissed that it was such an "easy" fix. As you can see in my question I'm using Base64Utils which is part of the "com.google.gwt.user.server.Base64Utils" package. I think it's faulty somehow, either I'm using it wrongly or it uses some default character-encoding and ignores the encoding of the data that it receives, I simply don't know. I switched it out to use the Base64 from the "org.apache.commons.codec.binary.Base64" package, and it seems to work.

(It's worth mentioning that i did try to use the Base64Utils in combination with using getBytes("UTF-8") - but that didn't work either.)

So the working method looks like this:

public String[] getPolicyAndSignature(String policy)
{
    try
    {
        String encodedPolicy = new String(Base64.encodeBase64(policy.getBytes()));

        KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(new FileInputStream(new File("my_test_app/mykey.p12")), "notasecret".toCharArray());
        PrivateKey privateKey = (PrivateKey)keystore.getKey("privatekey", "notasecret".toCharArray());

        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(encodedPolicy.getBytes());

        String encodedSignature = new String(Base64.encodeBase64(signature.sign(), false));

        return new String[]{encodedPolicy, encodedSignature};
    }
    catch(Exception e)
    {
        System.out.println("Error: " + e.getMessage());
    }
    return null;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top