Google Cloud Bucket - 上传文件 - 403 禁止 Android SignatureDoesNotMatch

Google Cloud Bucket - Upload File - 403 Forbidden Android SignatureDoesNotMatch

所以按照这里的 GCSSignedURLExample.java 示例

https://cloud.google.com/storage/docs/access-control#Construct-the-String

我试过eclipse中的代码。我的 mac 书中的简单 .java 文件程序。 而且效果很好。当我登录 console.developer.google.com 并浏览存储桶内容时,我可以看到创建的文本文件。

但是我尝试从 Android 执行的同一段代码。我收到 403 错误。

因此,当从 mac 的 .java 程序运行时,下面的代码工作正常。但是当在 android 中执行时,它给出 403.

如有任何帮助,我们将不胜感激。如果需要,我可以添加更多代码。

        key = loadKeyFromPkcs12(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret".toCharArray());

        System.out.println("======= PUT File =========");
        String put_url = this.getSigningURL("PUT");

        URL url = new URL(put_url);
        HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
        httpCon.setDoOutput(true);
        httpCon.setRequestMethod("PUT");
        OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream());
        out.write("Lorem ipsum");
        out.close();

        System.out.println("PUT Request URL: " + put_url);
        System.out.println("PUT Response code: " + httpCon.getResponseCode());
        renderResponse(httpCon.getInputStream());

编辑

好的,再调试 403 次,我发现它是一个 SignatureDoesNotMatch

<Code>SignatureDoesNotMatch</Code>
<Message>
    The request signature we calculated does not match the signature you provided. 
    Check your Google secret key and signing method.
</Message>

<StringToSign>PUT
    application/x-www-form-urlencoded
    1456322965
    /my-bucket/234/somerandomfile.txt
</StringToSign>

我还是想不通。这是签名代码。这与我在 eclipse java 代码(工作代码)

上所做的相同
private String getSigningURL(String verb) throws Exception {
    String url_signature = this.signString(verb + "\n\n\n" + expiration + "\n" + "/" + BUCKET_NAME + "/" + OBJECT_NAME  );
    String signed_url = "https://storage.googleapis.com/" + BUCKET_NAME + "/" + OBJECT_NAME +
            "?GoogleAccessId=" + SERVICE_ACCOUNT_EMAIL +
            "&Expires=" + expiration +
            "&Signature=" + URLEncoder.encode(url_signature, "UTF-8");
    return signed_url;
}

private PrivateKey loadKeyFromPkcs12(String filename, char[] password) throws Exception {

    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(getAssets().open(filename), password);
    return (PrivateKey) ks.getKey("privatekey", password);
}

private String signString(String stringToSign) throws Exception {
    if (key == null)
        throw new Exception("Private Key not initalized");
    Signature signer = Signature.getInstance("SHA256withRSA");
    signer.initSign(key);
    signer.update(stringToSign.getBytes("UTF-8"));
    byte[] rawSignature = signer.sign();
    return new String(Base64.encodeBase64(rawSignature, false), "UTF-8");
}

终于解决了。 没有直接的文件引导我到这里。

它是你在给我带来问题的动词后面加上的 \n 的数量。

检查这个 link https://cloud.google.com/storage/docs/access-control#Construct-the-String

String url_signature = this.signString(verb + "\n\n" 
+ "application/x-www-form-urlencoded" 
+ "\n" + expiration + "\n" + "/" + BUCKET_NAME + "/" + OBJECT_NAME  );