转换成clientsecret私钥(Convert a clientsecret into a pr

2019-08-17 04:39发布

我在AppEngine上与谷歌云存储工作,我试图用POST形式将文件上传到GCS。 我遇到的问题是与签政策文件所需的步骤。 我可以很容易地获取client_secret,这是从一个字符串client_secrets.json的API控制台给我。 然而,为了创建一个签名,我需要的是字符串转换成PrivateKey对象。 下面是我的代码如下所示:

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

正如上面提到的,我的问题是在该行

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

secretKey是一个字符串。 Signature.initSign()需要一个PrivateKey ,或它的子对象中的一个。 如何转换的字符串client_secrets.json成专用密钥(或派生)对象,我可以通过Signature.initSign

任何帮助将不胜感激。 谢谢

OK,这里是我的现在。 我想下面的建议,所有的文档催我使用client_secret从谷歌API控制台,而不是服务帐户下载的client_secrets.json档案。 除此之外,我试图构建一个用户的上传,而不是服务帐户的一个例子。

我发现了另一页上下面的代码:

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

它让我一路走过的过程......直到我提交生成的表单。 然后我得到以下回应:

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

它是在寻找什么签名方法?

Answer 1:

将文件从AppEngine上上传到GCS可以使用Blob存储API。 按照中介绍的步骤使用Blob存储区与GCS 。 其优点是,你不必担心键和代码要简单得多。



Answer 2:

这是我认为你需要做的:

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

keyBytes变量应该包含一个byte[]与您的阵列在其服务帐户的密钥文件 。



Answer 3:

最后回答这个问题就像是战棋的结论。 作为WOPR说,“一场奇怪的比赛...赢得的唯一方法就是不玩。” 避免签署和政策文件和所有的垃圾,并使用Blob存储区。

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

这是很容易实现; 当您创建的临时Blob存储上传网址如下所示:

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

这样做的缺点的方法是对象名称将是你不认识的字符的字符串。 您可以打开Blob存储区和观众看到文件名,你的对象在Blob存储区,但在其GCS对象名称将是官样文章。 (A散列,也许?随机分配的ID)?



文章来源: Convert a clientsecret into a private key