Convert a clientsecret into a private key

混江龙づ霸主 提交于 2019-12-21 06:18:28

问题


I'm working with Google Cloud Storage in AppEngine and I'm attempting to use a POST form to upload a file to GCS. The problem I'm having is with the steps needed to sign the policy document. I can easily fetch the client_secret, which is a String from the client_secrets.json that the API Console gave me. however, in order to create a signature, I need to convert that string into a PrivateKey object. Here's what my code looks like:

//create the policy document and encode it
String policyDocument = ...  //omitted for brevity
String encodedPolicy = Base64.encodeString(policyDocument);

//sign using SHA256 with RSA
String secretKey = ... //I fetch this from client_secrets.json
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(secretKey); //THIS IS THE PROBLEM!  
sig.update(encodedPolicy.getBytes("UTF-8"));        
String signature = new String(Base64.encode(sig.sign()));

//put the values in the request attributes so we can fetch them from a JSP
req.setAttribute("policy", encodedPolicy);
req.setAttribute("signature", signature);

As noted above, my problem is in the line

sig.initSign(secretKey); //THIS IS THE PROBLEM!  

secretKey is a String. Signature.initSign() expects a PrivateKey, or one of its descendant objects. How do I convert the string in the client_secrets.json into a PrivateKey (or derived) object that I can pass Signature.initSign?

Any help would be greatly appreciated. Thanks

OK, here's where I am right now. I tried the suggestions below, and all of the documentation is urging me to use the client_secret in the client_secrets.json file downloaded from the Google API console, not the service account. And besides, I'm trying to construct an example of a user's upload, not a service account.

I found the following code on another page:

public static String signPolicyDocument(String policyDocument, String secret) {     
try {
        Mac mac = Mac.getInstance("HmacSHA256");
        byte[] secretBytes = secret.getBytes();
        SecretKeySpec signingKey = new SecretKeySpec(secretBytes, "HmacSHA256");
        mac.init(signingKey);
        byte[] signedSecretBytes = mac.doFinal(policyDocument.getBytes());          
        return new String(Base64.encode(signedSecretBytes));
    } catch (InvalidKeyException e) {
        throw new RuntimeException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }

And it gets me all the way through the process...until I submit the resulting form. Then I get the following response:

The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.

What signing method is it looking for?


回答1:


To upload a file to GCS from Appengine you can use the blobstore Api. Follow the steps described in Using Blobstore with GCS. The advantage is that you don't have to worry about keys and the code is much simpler.




回答2:


Here's what I think you need to do:

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
sig.initSign(privateKey);

The keyBytes variable should contain a byte[] array with your service account key file in it.




回答3:


The final answer to this problem is like the conclusion of Wargames. As WOPR said, "A strange game...the only way to win is not to play." Avoid signing and policy document and all that crap and use the blobstore.

(See this: https://developers.google.com/appengine/docs/java/blobstore/overview#using-blobstore-with-gcs)

It's very easy to implement; when you create your temporary blobstore upload URL like so:

    //open the blobstore service and create the upload url
    BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService();        
    String uploadUrl = bs.createUploadUrl("/display",
            UploadOptions.Builder.withGoogleStorageBucketName(bucket));

The downside to this approach is the object name will be a string of characters you don't recognize. You can open the blobstore viewer and see your object by file name in the blobstore, but in GCS its object name will be gobbledygook. (A hash, maybe? A randomly assigned ID)?



来源:https://stackoverflow.com/questions/15084452/convert-a-clientsecret-into-a-private-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!