Android SafetyNet JWT签名验证

时间:2017-07-24 23:12:18

标签: android validation jwt digital-signature safetynet

我正在尝试了解jwt签名验证的工作原理。

这就是我现在正在做的事情:

1) My app calls the attest api
2) My app sends the jwt to my server
3) My server verify the signature (third field of the jwt) using the certificate provided in the header of the jwt.

据我所知,签名是通过散列jwt的标头和有效负载创建的,然后使用Google的私钥对其进行签名(加密)。

我在第3步中所做的是我使用标头+有效负载并使用它解密 证书的公钥并验证它是否与签名匹配。 (当我说'我'的意思是说我做的时候)

我的问题是,如果用户设备上存在恶意软件并且即时修改发送到我的服务器的JWT会发生什么?恶意软件会在标头中添加自己的证书(由可信CA发布),按照自己的意愿修改有效负载并创建签名。

我服务器端......好吧,我将把证书中提供的公钥与其匹配的签名有效。

这是对的吗?或者我在某处感到困惑?因为在那种情况下它会使这一切流程都没用了没有?怎么保证自己100%JWT来自谷歌?

2 个答案:

答案 0 :(得分:2)

关键点是验证签名证书是否由受信任的证书颁发机构颁发给attest.android.com

任何受信任的CA都会向attest.android.com发出虚假证书。看看如果他们参与不良行为会发生什么https://security.googleblog.com/2016/10/distrusting-wosign-and-startcom.html?m=1

请参阅Google的doc

  

验证兼容性检查响应

     

您应该采取措施确保兼容性检查响应实际来自SafetyNet服务,并包含与您的请求数据匹配的数据。

     

警告:您应该使用安全连接将整个JWS响应发送到您自己的服务器进行验证。我们建议您不要直接在应用中执行验证,因为在这种情况下,无法保证验证逻辑本身没有被修改。

     

按照以下步骤验证JWS消息的来源:

     
      
  1. 从JWS消息中提取SSL证书链。

  2.   
  3. 验证SSL证书链并使用SSL主机名匹配来验证是否已将叶证书颁发给主机名attestanceandand.com.com。

  4.   
  5. 使用证书验证JWS消息的签名。

  6.   
  7. 检查JWS消息的数据,确保它与原始请求中的数据匹配。特别是,请确保nonce,timestamp,包名称和SHA-256哈希值匹配。

  8.   

第二个点需要验证证书链。假设它使用包含证书颁发机构的根证书的信任管理器

我已在OfflineVerify中检查了Google的示例代码,以确保TrustManager的存在,因为它没有明确说明,并且在JWS验证期间有效使用。它使用默认系统TrustManager,但您可以使用自定义系统

请注意,它使用的是JWS(Json Web Signature),而不是JWT。 JWT通常是使用JWS签名的身份验证令牌

答案 1 :(得分:0)

你确实正确地掌握了这个概念。但是,您忽略的一点是,您使用的lib可能会验证从中提取公钥的证书是否有效并且是受信任的?证书(AKA来自可信任的CA)

由于这一点(并且与文档指出的一样),您需要验证证书是否已由" attest.android.com"发布。没有人能够伪造证书使其来自这个CA,因为。

这是我至少理解的,如果我错了,请纠正我。