Security 脱机验证Azure AD生成的JWT

Security 脱机验证Azure AD生成的JWT,security,jwt,azure-active-directory,Security,Jwt,Azure Active Directory,验证Azure AD生成的令牌时出错。这是当前设置: 我有一个可以粘贴的令牌,我可以在右侧面板中看到正确的声明。我假设令牌的格式正确。我还可以在标题中看到kid=piVlloQDSMKxh1m2ygqGSVdgFpA和alg:RS256。我正确地将algo类型设置为RS256以进行验证 我去查找公钥,找到了相同的kid=piVlloQDSMKxh1m2ygqGSVdgFpA。因此,我复制了相应的公钥(x5c字段中的字符串),并将其包装到正确的字符串中,使其成为PKCS#8。兼容: -----开

验证Azure AD生成的令牌时出错。这是当前设置:

  • 我有一个可以粘贴的令牌,我可以在右侧面板中看到正确的声明。我假设令牌的格式正确。我还可以在标题中看到
    kid=piVlloQDSMKxh1m2ygqGSVdgFpA
    alg:RS256
    。我正确地将algo类型设置为RS256以进行验证

  • 我去查找公钥,找到了相同的
    kid=piVlloQDSMKxh1m2ygqGSVdgFpA
    。因此,我复制了相应的公钥(x5c字段中的字符串),并将其包装到正确的字符串中,使其成为PKCS#8。兼容:

    -----开始证书----- Miidbccae2gawibagiqmCJCGWF4L5xPEOWB7DKDANBGKKQHKIG9W0BAQSFADATMSWKQYDVQQDEYJ2NVDW50CY5HY2LC3NJB250CM9SLNDPBMRVD3MUBMV0MB4XDTE5MTextantawmFloxDTI0MTexDawmbowltermWowltermCKGA1EAXMYWWWW3VudHJMUYWW5B3DZLD5LDDCCASIWYJJJJJJ5W5W5W5W5W5YKZYKZYKZJJJ5LDJJJJJJJJJJJJ5YKZZYKZYYKZYKZYKZYKZYKZJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ5YY(2)一个单词(2)是一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词,一个单词WUAA4IBAQA6GQ(2)2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2(2)2)2(2)2(2)2(2)2)2(2)2)2(2)2)2(2)2)2(2)2)2(2)2)2(2)2)2)2(2)2)2(2)2)2)2(2)2)2)2(2)2)2)2)2)2(2)2)2)2)2)2(2)2)2)2)2(2)2)2)2)2)2(2)2)2)2)2)2)2(2)2)2)2)2)2)2(2(2)2)2)2)2)2)2)2)2)2)2)2)2)2)2)TCEFEXNTZ -----结束证书-----

如果上面不可见,则在
----开始证书---
之后和
----结束证书---
之前都有一个
\n

  • 公钥被复制到它的公钥部分,在我的代码中它是RSA公钥
  • 我还尝试使用PKCS#1格式化,但没有获得更多成功
它一直是无效的。甚至没有过期,在jwt.io和我的代码中都明显无效


假设令牌是正确的,我的方法正确吗?我发现准备.pem的教程不同。如果我的令牌不正确,除了从它那里获得声明之外,我如何检查它?

您需要从
模数和
指数生成公钥

您可以从
https://login.microsoftonline.com/{tenantId_或_commom}/discovery/v2.0/keys

以下是供您参考的java示例:

    public static PublicKey getPublicKey(String encodedModulus, String encodedExponent) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] modulus = Base64.getUrlDecoder().decode(encodedModulus);
        byte[] exponent = Base64.getUrlDecoder().decode(encodedExponent);

        StringBuilder sb = new StringBuilder();
        for (byte b : modulus) {
            sb.append(String.format("%02x", b));
        }
        String sm = sb.toString();

        sb = new StringBuilder();
        for (byte b : exponent) {
            sb.append(String.format("%02x", b));
        }
        String se = sb.toString();

        BigInteger bm = new BigInteger(sm,16);
        BigInteger be = new BigInteger(se,16);

        KeyFactory rsa = KeyFactory.getInstance("RSA");
        PublicKey publicKey = rsa.generatePublic(new RSAPublicKeySpec(bm, be));

        return publicKey;
    }


    public static void main(String[] args) throws Exception {
        String modulus = "0XhhwpmEpN-jDBapnzhFbtvEU2BpLLcaLzlXm4mlT2MwKZlXRUUam2vI0URDUYRKaa4O62BCWSSGOv2LGQ6tMD5oU-Dqkuf44bo1hLufIqAALUymssfRurTrLd0fqVA9ZCF3fA8_7xQi5r370m4h-G71ez8eE3lxiVPlwSeJXRpa5QzGA8ApwbXGiV-6liGU4eMXBU39A5rFy6TdioaC4P6xns-IdwlLMWdOR28P4O0yhbVTqcN_kW4N4AQonslB_tGOJGhWJjFkcqsQ8cbiJn6Q6FXoNADXohJO3sAtdUHyBNMXc68i25uTYTe_qyCKuC290TkyR3gxMlw7rtuB1Q";
        String exponent = "AQAB";
        byte[] bytes = getPublicKey(modulus, exponent).getEncoded();
        String encodedString = new String(Base64.getEncoder().encode(bytes));

        System.out.println("-----BEGIN PUBLIC KEY-----");
        System.out.println(encodedString);
        System.out.println("-----END PUBLIC KEY-----");

        System.out.println();
    }
您将获得以下一些输出:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0XhhwpmEpN+jDBapnzhFbtvEU2BpLLcaLzlXm4mlT2MwKZlXRUUam2vI0URDUYRKaa4O62BCWSSGOv2LGQ6tMD5oU+Dqkuf44bo1hLufIqAALUymssfRurTrLd0fqVA9ZCF3fA8/7xQi5r370m4h+G71ez8eE3lxiVPlwSeJXRpa5QzGA8ApwbXGiV+6liGU4eMXBU39A5rFy6TdioaC4P6xns+IdwlLMWdOR28P4O0yhbVTqcN/kW4N4AQonslB/tGOJGhWJjFkcqsQ8cbiJn6Q6FXoNADXohJO3sAtdUHyBNMXc68i25uTYTe/qyCKuC290TkyR3gxMlw7rtuB1QIDAQAB
-----END PUBLIC KEY-----
然后您可以在jwt.io中使用它:

非常有帮助,快到了!我把它编码在我这边,我有和你一样的公钥,这是令人鼓舞的。此外,它与上的公钥的默认文本框中显示的内容相同(他们是如何获得的?)。尽管如此,它还没有被标记为已验证。我不知道下一步该去哪里看,可能是被截断的令牌吗?在这种情况下,令牌调试器还会自动找到正确的公钥吗?请共享您得到的令牌好吗?过期的就可以了。顺便问一下,我可以知道您是否获得了Microsoft Graph API的令牌吗?如果您获得了Graph API的令牌,则该令牌包含一个nonce,需要在验证期间进行特殊处理。换句话说,只有图形才能验证它。有关这方面的更多信息,您可以参考Github问题页面:,@NLASSUX有一些新发现,请查看上面的评论。