来自Azure AD的JWT令牌签名验证失败

时间:2020-03-20 17:10:52

标签: azure jwt azure-active-directory openid-connect

this MS info about client credential grants之后,我得到了JWT令牌:

eyJ0eXAiOiJKV1QiLCJub25jZSI6InBOWU1CVkZKcFAxVjJ1VTFaUnM1V3NOLVhyeDhjXzhWWjU5RWxhTFZBeDAiLCJhbGciOiJSUzI1NiIsIng1dCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSIsImtpZCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8wMmRhZjUwZC00ZDFlLTRhOTUtYTI0YS1jOTg3MDUzNDBlYzAvIiwiaWF0IjoxNTg0NzIwNjk3LCJuYmYiOjE1ODQ3MjA2OTcsImV4cCI6MTU4NDcyNDU5NywiYWlvIjoiNDJOZ1lIaTZxVjRxS0xoLzRteUd0UzBmb3lLWEFRQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJSc2tUZXN0QXBwIiwiYXBwaWQiOiJlMjcwYmNkNC00ZDU0LTRiN2MtYWFmYy1hYjUyZWZmMjA5N2UiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8wMmRhZjUwZC00ZDFlLTRhOTUtYTI0YS1jOTg3MDUzNDBlYzAvIiwib2lkIjoiMGQ3MDU2NWItZWQzMi00ZGMzLWJmMTYtOWFjMTRjOTVlYzJiIiwic3ViIjoiMGQ3MDU2NWItZWQzMi00ZGMzLWJmMTYtOWFjMTRjOTVlYzJiIiwidGlkIjoiMDJkYWY1MGQtNGQxZS00YTk1LWEyNGEtYzk4NzA1MzQwZWMwIiwidXRpIjoiMVVxeV9PemJJMDZOSGp6VHo1Qm9BQSIsInZlciI6IjEuMCIsInhtc190Y2R0IjoxNTg0NzE3OTU0fQ.fy2TIhXb89Ic2wuw7ysao-JzBqzpQGHD29A_X-JRJ eEXOTvO5AB75tn0G1zV69vYkg2hEMsv3Dej5pNJ82w8NETRXMEEhC6ke9-URk0uKzWJ_ZzxNrL9I1eD8N4UUhqXeJifYE9gatDRqSfFmEn5eQbRVgEegJMmpqb7DMeUH8pOkTZLKzFHjSmJATx2eQBkW1PiMEL5u-QuIiZohObxficQ8PvK-IgE2V_LcTuVnEVXBrgYfZllPesQTP9-fjV_iGnM5gwcnVhwqNdpk9Ws-Vz2XDgRRCDu604IbYv3SvA9JhbKByo0CPreMfhqjrP5l_0Rm_bJeGj9iJrql5Jj3w

当我简单地将其复制粘贴到jwt.io时,令牌已正确解码,但其签名验证失败。 因此我怀疑jwt.io无法正常工作,并想亲自验证令牌。

令牌的标题:

{
  "typ": "JWT",
  "nonce": "pNYMBVFJpP1V2uU1ZRs5WsN-Xrx8c_8VZ59ElaLVAx0",
  "alg": "RS256",
  "x5t": "YMELHT0gvb0mxoSDoYfomjqfjYU",
  "kid": "YMELHT0gvb0mxoSDoYfomjqfjYU"
}

根据this description where the Azure public keys/certificates are available,我取了它们,并且有 kid = YMELHT0gvb0mxoSYfomjqfjYU 的密钥在那里:

{
     "kty":"RSA",
     "use":"sig",
     "kid":"YMELHT0gvb0mxoSDoYfomjqfjYU",
     "x5t":"YMELHT0gvb0mxoSDoYfomjqfjYU",
     "n":"ni9SAyu9EsltQlV7Jo3wMUvcpYb4mmfHzV4IsDZ6NQvJjtQJuhsfqiG86VntMd76R44kCmkfMGvtQRA2_UmnVBSSLxQKvcGUqNodH7YaMYOTmHlbOSoVpi3Ox2wj6cWvhaTTm_4xzJ3F0yF0Y_aRBMxSCIwLv3nTMRNe74k4zdBnhL7k5ObOY_vUGt_5-sPo6BXoV7oov4Ps6jeyUdRKtqVZSp5_kzz16kPh1Ng_2tn4vpQimNbHRralq8rNM_gOLPAar6v7mL_qsqpgx-48e5ENFxikbB-NzAmLll1QSkzciu2rCjFGH4j_-bCHr7FxUNDL_E0vMFVDFw8SUlYMgQ",
     "e":"AQAB",
     "x5c":[
        "MIIDBTCCAe2gAwIBAgIQG4GFMDOjD7lKSdsgshqQ/DANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTIwMDIwNTAwMDAwMFoXDTI1MDIwNDAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4vUgMrvRLJbUJVeyaN8DFL3KWG+Jpnx81eCLA2ejULyY7UCbobH6ohvOlZ7THe+keOJAppHzBr7UEQNv1Jp1QUki8UCr3BlKjaHR+2GjGDk5h5WzkqFaYtzsdsI+nFr4Wk05v+McydxdMhdGP2kQTMUgiMC7950zETXu+JOM3QZ4S+5OTmzmP71Brf+frD6OgV6Fe6KL+D7Oo3slHUSralWUqef5M89epD4dTYP9rZ+L6UIpjWx0a2pavKzTP4DizwGq+r+5i/6rKqYMfuPHuRDRcYpGwfjcwJi5ZdUEpM3IrtqwoxRh+I//mwh6+xcVDQy/xNLzBVQxcPElJWDIECAwEAAaMhMB8wHQYDVR0OBBYEFHssLV3w8SFEdZk03/TJwDfWQ6mRMA0GCSqGSIb3DQEBCwUAA4IBAQAh9iGtY+wKAMrYYLCU8uRZnUY9f+s936HhZdnJfVCuJM7y3fIbzvPO0T0dMHLz++ba0rkptoe+HjZaNA7vVwzdEtAdNff0wFef470sb+kxPi64PZK/IhtqBEwEvy090ZwGsZqM/Ut9QxFH21/t/wcz0wUBc6QGGxgWr1T/Qfzlemnz5DxuHaKQdiafz6yrwGyVjmaRkjMqeqhQy3J0nNoJNbofopSnnGH0g5IWBJBJPBk7k8RaliY0i+GwTliCgiI59ZPt1dS1+EXfNS06v1+TjTe1tPHyGot03i+iIA3WJk3REgT14y7Rhl94htzmMFmrlGNioXlfLFx9fDJQkJfz"
     ],
     "issuer":"https://login.microsoftonline.com/{tenantid}/v2.0"
}

接下来,我从证书中提取公钥:

openssl x509 -in ms_signing_cert4.pem -pubkey -noout

-----开始公开密钥----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAni9SAyu9EsltQlV7Jo3w MUvcpYb4mmfHzV4IsDZ6NQvJjtQJuhsfqiG86VntMd76R44kCmkfMGvtQRA2 / Umn VBSSLxQKvcGUqNodH7YaMYOTmHlbOSoVpi3Ox2wj6cWvhaTTm / 4xzJ3F0yF0Y / aR BMxSCIwLv3nTMRNe74k4zdBnhL7k5ObOY / vUGt / 5 + sPo6BXoV7oov4Ps6jeyUdRK tqVZSp5 / kzz16kPh1Ng / 2tn4vpQimNbHRralq8rNM / gOLPAar6v7mL / qsqpgx + 48 e5ENFxikbB + NzAmLll1QSkzciu2rCjFGH4j / + bCHr7FxUNDL / E0vMFVDFw8SUlYM gQIDAQAB -----结束公钥-----

最后,我使用Python PyJWT库来验证签名:

import jwt

token = 'eyJ0eXAiOiJKV1QiLCJub25jZSI6InBOWU1CVkZKcFAxVjJ1VTFaUnM1V3NOLVhyeDhjXzhWWjU5RWxhTFZBeDAiLCJhbGciOiJSUzI1NiIsIng1dCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSIsImtpZCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8wMmRhZjUwZC00ZDFlLTRhOTUtYTI0YS1jOTg3MDUzNDBlYzAvIiwiaWF0IjoxNTg0NzIwNjk3LCJuYmYiOjE1ODQ3MjA2OTcsImV4cCI6MTU4NDcyNDU5NywiYWlvIjoiNDJOZ1lIaTZxVjRxS0xoLzRteUd0UzBmb3lLWEFRQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJSc2tUZXN0QXBwIiwiYXBwaWQiOiJlMjcwYmNkNC00ZDU0LTRiN2MtYWFmYy1hYjUyZWZmMjA5N2UiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8wMmRhZjUwZC00ZDFlLTRhOTUtYTI0YS1jOTg3MDUzNDBlYzAvIiwib2lkIjoiMGQ3MDU2NWItZWQzMi00ZGMzLWJmMTYtOWFjMTRjOTVlYzJiIiwic3ViIjoiMGQ3MDU2NWItZWQzMi00ZGMzLWJmMTYtOWFjMTRjOTVlYzJiIiwidGlkIjoiMDJkYWY1MGQtNGQxZS00YTk1LWEyNGEtYzk4NzA1MzQwZWMwIiwidXRpIjoiMVVxeV9PemJJMDZOSGp6VHo1Qm9BQSIsInZlciI6IjEuMCIsInhtc190Y2R0IjoxNTg0NzE3OTU0fQ.fy2TIhXb89Ic2wuw7ysao-JzBqzpQGHD29A_X-JrjeEXOTvO5AB75tn0G1zV69vYkg2hEMsv3Dej5pNJ82w8NETRXMEEhC6ke9-URk0uKzWJ_ZzxNrL9I1eD8N4UUhqXeJifYE9gatDRqSfFmEn5eQbRVgEegJMmpqb7DMeUH8pOkTZLKzFHjSmJATx2eQBkW1PiMEL5u-QuIiZohObxficQ8PvK-IgE2V_LcTuVnEVXBrgYfZllPesQTP9-fjV_iGnM5gwcnVhwqNdpk9Ws-Vz2XDgRRCDu604IbYv3SvA9JhbKByo0CPreMfhqjrP5l_0Rm_bJeGj9iJrql5Jj3w'
pub_key = b'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAni9SAyu9EsltQlV7Jo3w\nMUvcpYb4mmfHzV4IsDZ6NQvJjtQJuhsfqiG86VntMd76R44kCmkfMGvtQRA2/Umn\nVBSSLxQKvcGUqNodH7YaMYOTmHlbOSoVpi3Ox2wj6cWvhaTTm/4xzJ3F0yF0Y/aR\nBMxSCIwLv3nTMRNe74k4zdBnhL7k5ObOY/vUGt/5+sPo6BXoV7oov4Ps6jeyUdRK\ntqVZSp5/kzz16kPh1Ng/2tn4vpQimNbHRralq8rNM/gOLPAar6v7mL/qsqpgx+48\ne5ENFxikbB+NzAmLll1QSkzciu2rCjFGH4j/+bCHr7FxUNDL/E0vMFVDFw8SUlYM\ngQIDAQAB\n-----END PUBLIC KEY-----'

print(jwt.decode(token, pub_key, algorithms=['RS256']))

结果

jwt.exceptions.InvalidSignatureError:签名验证失败

我试图在PC上生成自己的JWT,该JWT也由RS256签名-通过jwt.io和PyJWT传递。我在网上某处找到的示例令牌也是如此。只是无法处理AAD发行的令牌。

这些AAD代币我缺少什么? 非常感谢。

2 个答案:

答案 0 :(得分:1)

您的令牌是正确的。它只是图API的特定标记。您将在Jwt.Header中看到一个nonce。这意味着您需要特殊处理。正常处理将失败。

如果您是获得Graph令牌的客户,请假设它是一个 永远不要看的加密字符串-有时会这样。 我们为Graph使用一种特殊的令牌格式,他们知道如何验证 -如果访问令牌不适合您,则不应查看。

查看详细信息here

参考:

Can not validate signature

答案 1 :(得分:0)

是的。此随机数位于V2中,是V1令牌的附加内容。 我曾经使用此代码段验证V1:

                var signatureKey = signatureKeyIdentifier.X509CertificateChain.First();
                var certificate = new X509Certificate2(signatureKey.ToBytesFromBase64URLString());
                var rsa = certificate.GetRSAPublicKey();
                var data = string.Format("{0}.{1}", header, payload).ToBytes();
                var isValidSignature = rsa.VerifyData(
                    data,
                    signature.ToBytesFromBase64URLString(),
                    HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);

但是现在此验证将失败。 请注意,我正在创建标题提供的证书。 随机数与签名无关,它只是每个请求/令牌更改的数字,以确保没有人重播该有效令牌。通过将所有随机数保存在数据库中并检查唯一性来验证随机数。 我认为我们需要找出计算签名的变化。他们还在使用相同的填充吗?同样的算法?

我现在用来验证的方法是将令牌发送到同一活动目录以获取数据,然后AD仅在有效令牌后才提供数据。