当前位置: 首页 > 知识库问答 >
问题:

使用公钥的Microsoft Graph AccessToken签名验证

颛孙玉石
2023-03-14

我需要验证来自Microsoft图形API的令牌签名。我知道所使用的签名键的指纹在JWT的标题中:

它对应于您可以从已知endpoint获得的密钥:

https://login.microsoftonline.com/[TENANT-ID]/发现/v2.0/key

我的计划是将密钥列表存储在缓存中,以便在需要进行验证时可以查找令牌的正确签名密钥。然而,我明白有时键可能会旋转。

由于没有太多关于这方面的文件,我的问题分为多个部分:

>

  • 这是一个合理的策略吗?

    新密钥是否会附加到已知终结点的列表中?我假设这个列表随着时间的推移而增长,所以如果令牌需要它,我总是可以得到一个旧的密钥?以及刷新我的缓存,如果它需要用可用的密钥重新水合。

    旧的键在什么时候从列表中删除?我想一定有一个时间或计数截止。

    似乎最新的键是第一条记录,并按降序排序?

    为什么x5c是一个数组?每个记录不应该只有一个签名键吗?我假设我应该只使用. x5c[0],但是在什么情况下这里会有多个项目?

  • 共有1个答案

    汪庆
    2023-03-14

    在各种库中为您实现了密钥滚动;一个好的策略是使用其中之一,而不是自己滚动。

    来自https://login.microsoftonline.com/[TENANT-ID]/发现/v2.0/key的JSON文档符合JSON Web Key(JWK)规范(RFC 7517)。规范没有规定key数组中键的顺序:

    “keys”参数的值是JWK值的数组。默认情况下,数组中JWK值的顺序并不意味着它们之间的优先顺序,尽管JWK集的应用程序可以根据需要为顺序指定意义。

    Microsoft的密钥滚动实现似乎将较新的密钥添加到列表的顶部。对此没有书面保证,我们不建议依赖它。当关键点从列表中删除时,同样没有发布此规范。如果证书被吊销或过期,则无法使用该证书验证签名。根据常识,应该在那个时候将其从列表中删除。微软的关键滚动文档指出

    在紧急情况下,[钥匙]可以立即翻转过来。

    翻译:决定您应该多长时间返回https://login.microsoftonline.com/[租户ID]/discovery/v2。0/密钥取决于无法验证应用程序中令牌的重要性/后果。

    x5c是一个数组,因为它代表一个证书链。微软的实现是使用单个证书(链的长度=1),但没有什么能阻止他们在将来某个时间点使用更长的链。实际上,他们不太可能这样做,因为这将影响许多不符合要求的应用程序以及他们自己的库。

     类似资料:
    • 问题内容: 我有一个外部服务,在定义的事件发生后会给我回电,并用其私钥签署他的请求。 我已经存储了如下公钥: 因此,我的工作是通过验证签名来检查请求的内容是否未更改。 这是我的算法: 但是目前,我的算法已停止在此消息的“ PublicKey publicKey = keyFactory.generatePublic(publicKeySpec)”步骤处: 那么,如何以java api接受的方式加载

    • 验证应用程序: 据我所知.pfx文件包含公钥和私钥信息,因此我不应该让任何人都可以使用它。据我所知,验证步骤只需要公钥。我如何使用rsa.verifydata或其他函数来验证签名而不暴露我的pfx文件?

    • 我的理解是公钥加密,私钥解密...有谁能帮我弄明白吗?

    • 我想验证一些来自Microsoft的JWT的签名。我正在使用Spring-Boot、JJWT库和以下endpoint:https://login.microsoftonline.com/common/discovery/v2.0/keys endpoint返回JSON公钥数组。下面是数组中的一个示例。

    • 我需要用DSA公钥验证X509证书签名。我的证书文件x509.crt,我的DSA公钥在一个名为dsa_pub.key的文件中 我正试图为此使用openssl。我已经阅读了openssl验证文档,但在其中找不到任何有关DSA的参考。 当我运行以下命令时,我可以在证书中看到我的DSA公钥: 但是,在使用文件DSA_pub.key中的DSA公钥验证cert.crt时,我遇到了麻烦 如果您有任何建议,我将

    • 另外,这里还有一个函数演示,它从mod和指数生成PEM(摘自http://stackoverflow.com/questions/18835132/xml-to-pem-in-node-js) 前面提到的jsonwebtoken库可以使用任何一种方法来验证JWT--但是为什么呢?如果这两种验证方法都可以验证一个JWT签名,为什么它们都存在呢?他们之间有什么权衡?一个比另一个更安全吗?我应该使用哪一