【问题标题】:Get key for Google Safety net获取 Google 安全网的密钥
【发布时间】:2020-04-17 12:52:18
【问题描述】:

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

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

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

我已经成功验证了使用 google api 调用接收到的 jwt 的签名:

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

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

我应该像这样验证签名:

jwt.verify(signedAttestation, key)

问题是我不知道在哪里可以找到这个密钥,它显然不是 APIKey,Google 提供了一些示例代码,但它是 Java 或 C#,我显然无法将它翻译成 node js .可在此处获得:https://github.com/googlesamples/android-play-safetynet/ 我正在尝试专注于离线验证:https://github.com/googlesamples/android-play-safetynet/blob/master/server/java/src/main/java/OfflineVerify.java 欢迎任何帮助,非常感谢。

【问题讨论】:

标签: java node.js kotlin certificate google-signin


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 2011-11-28
    • 2021-07-09
    • 2017-01-30
    • 2013-08-27
    相关资源
    最近更新 更多