Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法使用x5c(x509)公共证书验证JWT_Javascript_Encryption_Jwt_X509_Jwk - Fatal编程技术网

Javascript 无法使用x5c(x509)公共证书验证JWT

Javascript 无法使用x5c(x509)公共证书验证JWT,javascript,encryption,jwt,x509,jwk,Javascript,Encryption,Jwt,X509,Jwk,更新 我试图使用下面的x5c/x509公钥值以编程方式验证JWT访问令牌。我可以通过将令牌和x5c值插入外部web站点而不是通过JavaScript/jsrsasign编程来实现这一点。如有任何建议,将不胜感激 以下是OIDC提供程序的公共JSON Web密钥集 { "keys": [ { "kty": "RSA", "kid": "server", "

更新 我试图使用下面的x5c/x509公钥值以编程方式验证JWT访问令牌。我可以通过将令牌和x5c值插入外部web站点而不是通过JavaScript/jsrsasign编程来实现这一点。如有任何建议,将不胜感激

以下是OIDC提供程序的公共JSON Web密钥集

    {
        "keys": [
            {
                "kty": "RSA",
                "kid": "server",
                "use": "sig",
                "alg": "RS256",
                "n": "gLZO9w1OT_SWO-KbqiU0k3HevHggiY70XbDqgE1YaqhD-MwFUWNudExzF3oB28NYWYg5v6CJY0F-pUNtgukDM6ARDlh0n4xIvBRlnUnCTCx7pYOjpfXbTv49tlXmh4-ddh8EeQBLrF92u5UYs0tnZd8843mvYWohUNH1X1hM08-hpk7xCiy4XdwbeSlH757D2d5E0J0dGtZ744-dB2ZRCw2Vms_mk4Yyny4ifx2j2gIhikbb7WGmsTR2sWrtuhgZ_EBNUvrD0O54xbhQNTTFQ1pi9UZxo_gYc5Gp5fLcSOK6SDBKXbDS5hhy1vFyoa0xdgFv-xpem7YzmkKqzfjC9w",
                "e": "AQAB",
                "x5c": [
                    "MIIDMDCCAhigAwIBAgIEFIopYzANBgkqhkiG9w0BAQsFADBaMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkwBwYDVQQKEwAxCTAHBgNVBAsTADEhMB8GA1UEAxMYZmNpc2Rldi5pY2UuaWJtY2xvdWQuY29tMB4XDTE4MTAwMTE4MTYyOFoXDTI4MDkyODE4MTYyOFowWjEJMAcGA1UEBhMAMQkwBwYDVQQIEwAxCTAHBgNVBAcTADEJMAcGA1UEChMAMQkwBwYDVQQLEwAxITAfBgNVBAMTGGZjaXNkZXYuaWNlLmlibWNsb3VkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIC2TvcNTk/0ljvim6olNJNx3rx4IImO9F2w6oBNWGqoQ/jMBVFjbnRMcxd6AdvDWFmIOb+giWNBfqVDbYLpAzOgEQ5YdJ+MSLwUZZ1Jwkwse6WDo6X1207+PbZV5oePnXYfBHkAS6xfdruVGLNLZ2XfPON5r2FqIVDR9V9YTNPPoaZO8QosuF3cG3kpR++ew9neRNCdHRrWe+OPnQdmUQsNlZrP5pOGMp8uIn8do9oCIYpG2+1hprE0drFq7boYGfxATVL6w9DueMW4UDU0xUNaYvVGcaP4GHORqeXy3EjiukgwSl2w0uYYctbxcqGtMXYBb/saXpu2M5pCqs34wvcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAdtN9znA9a6luPAQurcQn8kJBlllslRWsNPMhPWpMtYaMLx6JhmDICGbaYZBGUboedwnUaEk6tE2b+EVlUE/tnaKVJms2cmCCFExQQrTHmRfFI/Vi/esVqAnz1E2dB61LMnQ2AeebXAZ/C7hRt1uXVboXr5Zokppr4FRS9QsjSK4dhcXxhfglTKJOPZ4dkSexhe6hybpL8XdGhoyf2SyNXCy5iYX0zQ5BmJaLimOcJyasZ/A7/YgsVbQyAe6Ubno6/sIUuOZ+J+snZsBSLViqcftGVPUkIWamv/yNQcEJrDWa4C+sr+9Yb7uFjuj4gDY0jvGkGmu53g0K8Vks+IfAdQ=="
                ],
                "x5t#S256": "nTAGJuFFrm-vNBdkLVNmuePwTmlXr0T87IppgJPRT9k"
            }
        ]
    }
下面是我用来用x5c验证访问令牌的代码。我的印象是,我应该使用x5c值,但如果有其他方法,我也可以。只需使用密钥下的上述值验证令牌

// break line every 64 characters.

x5cValue = x5cValue.replace(/(.{64})/g, "$1\n");

// base64 decode

var x5cValueAtob = atob(x5cValue);

// Add Begin / END certificate

x5cValue = "-----BEGIN CERTIFICATE-----\n" + x5cValueAtob + "\n-----END CERTIFICATE-----";

var decoded = KJUR.jws.JWS.verify(accessTokenJson, rawContent, ["RS256"]);
我是否应该在base64解码之前/之后将开始/结束公钥字符串添加到x5c值?是的,多亏了亚当

验证前是否需要处理x5c值

返回的响应-已解码:false


提前感谢。

此答案可能无法帮助您回答所有问题,但我必须撰写此答案以提高解决方案的安全性

我觉得我应该使用x5c值,
验证前是否需要处理x5c值

从安全角度来看-不要使用x5c证书直接验证签名。在这种情况下,任何人都可以提供自己的证书并伪造任何身份

如果x5t/x5t#S256标头的目的是识别签名者-检查您是否信任指定iss下x5c或x5t#S256(或其颁发者)提供的证书,只有这样您才能验证签名。x5t标头使您的服务能够验证来自多个IdP(身份提供者/令牌颁发者)的令牌,或者在不失去服务提供者信任的情况下更新签名者的证书

如果您只信任使用单个证书的单个身份提供程序,则可以直接使用该提供程序的证书,而无需对提供的头执行任何操作


对于解决方案-似乎Adam在评论中是正确的,我还建议您使用加载/解析证书

我花了一天时间挠头,终于让它正常工作了

public static PublicKey getPublicKey(String x5c) throws CertificateException, IOException {
    System.out.println(" x5c ="+x5c);
    String stripped = x5c.replaceAll("-----BEGIN (.*)-----", "");
    stripped = stripped.replaceAll("-----END (.*)----", "");
    stripped = stripped.replaceAll("\r\n", "");
    stripped = stripped.replaceAll("\n", "");
    stripped.trim();
    System.out.println(" stripped ="+stripped);
    byte[] keyBytes = Base64.decode(stripped);
    CertificateFactory fact = CertificateFactory.getInstance("X.509");
    X509Certificate cer = (X509Certificate) fact.generateCertificate(new ByteArrayInputStream(keyBytes));
    return cer.getPublicKey();

}

看起来是的:我尝试在base64解码之前添加以下内容,但得到了相同的错误。x5cValue=“----开始证书------”+x5cValue+“----结束证书------”;事实上,亚当你让我思考,我添加了开始/结束文本和每64个字符换行。现在我发送这样的消息来验证,错误变为-false。我想我越来越接近了:)我不知道,但我认为您仍然需要解码开始和结束证书之间的x5cValue,因此它是
----开始证书------${atob(x5cValue)}----结束证书------
。不过,我很好奇一件事,你是需要验证代币,还是只是解码它来获取它的内容?谢谢亚当,尝试了你的建议。更新了上面的代码以显示。仍然得到错误的返回。