有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java获取Google安全网的密钥

试图阻止根设备运行我的应用程序

我想做的是验证我在应用程序上使用安全网api获得的签名认证的签名:

    SafetyNet.getClient(context).attest(byteArrayNonce, "MYAPIKEY")
            .addOnSuccessListener {

我已通过谷歌api调用成功验证收到的jwt签名:

https://www.googleapis.com/安卓check/v1/attestations/verify?key=${safetyAPIKey}(请求正文中带有signedAttestation)

一切都很好,谷歌告诉我验证成功了,但这项服务只是为了测试,我应该能够在我的服务器上验证签名。据我所知,为了验证jwt签名,我需要一个公钥。我使用https://www.npmjs.com/package/jws

我应该像这样验证签名:

jwt.verify(signedAttestation, key)

问题是我不知道在哪里可以找到这个密钥,它显然不是APIKey,谷歌提供了一些示例代码,但它是用Java或C#编写的,我显然无法将其转换为node js。可在此处找到:https://github.com/googlesamples/安卓-play-safetynet/ 我试着关注离线验证:https://github.com/googlesamples/安卓-play-safetynet/blob/master/server/java/src/main/java/OfflineVerify.java 欢迎任何帮助,非常感谢


共 (1) 个答案

  1. # 1 楼答案

    基本上,您需要执行一系列步骤来进行正确的验证。这里是the steps

    第三步是你需要做的事情

    我肯定会敦促您浏览所有的参考链接,以便更好地理解这个过程,并查看这里使用的每个库函数,以了解它们正在做什么,以及您是否希望它们做什么。我已经编写了伪代码来解释这些步骤

    // following steps should be performed
    // 1. decode the jws
    // 2. verify the source of the first certificate in x5c array of jws header 
    //    to be attest.google.com
    // 3. now to be sure if the jws was not tampered with, validate the signature of jws 
    //    with the certificate whose source we validated
    // 4. if the signature was valid, we need to know if the certificate was valid by 
    //    explicitly checking the certificate chain
    // 5. Validate the payload by matching the package name, apkCertificateDigest(base64 encoding of hashed your apps signing certificate)
    //    and nonce value
    // 6. and now you can trust the ctsProfileMatch and BasicIntegrity flags
    // let's see some code in node, though this will not run as-is, 
    // but it provides an outline on how to do it and which functions to consider
    
    const pki = require('node-forge').pki;
    const jws = require('jws');
    const pem = require("pem");
    const forge = require('node-forge');
    
    const signedAttestation = "Your signed attestation here";
    
    function deviceAttestationCheck(signedAttestation) {
      // 1. decode the jws
      const decodedJws = jws.decode(signedAttestation);
      const payload = JSON.parse(decodedJws.payload);
    
      // convert the certificate received in the s5c array into valid certificates by adding 
      // '  -BEGIN CERTIFICATE  -\n' and '  -END CERTIFICATE  -'
      // at the start and the end respectively for each element in the array
      // and by adding '\n' at every 64 char
      // you'll have to write your own function to do the simple string conversion
      // get the x5c certificate array
      const x5cArray = decodedJws.header.x5c;
      updatedX5cArray = doTheReformatting(x5cArray);
    
      // 2. verify the source to be attest.google.com
      certToVerify = updatedX5cArray[0];
      const details = pem.readCertificateInfo(certToVerify);
      // check if details.commanName === "attest.google.com"
    
      const certs = updatedX5cArray.map((cert) => pki.certificateFromPem(cert));
    
      // 3. Verify the signature with the certificate that we received
      // the first element of the certificate(certs array) is the one that was issued to us, so we should use that to verify the signature
      const isSignatureValid = jws.verify(signedAttestation, 'RS256', certs[0]);
    
    }
    

    所有帮助我的文章:

    1. 快速摘要-Here
    2. 过程说明-Here