Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.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
无法在Java中验证jwt签名_Java_Jwt_Json Web Token - Fatal编程技术网

无法在Java中验证jwt签名

无法在Java中验证jwt签名,java,jwt,json-web-token,Java,Jwt,Json Web Token,我试图通过验证JWT令牌的签名来验证它。但在验证过程中,我发现了一个错误 java.security.SignatureException:签名长度不正确:Get 342,但预期是256 。我假设签名是数据的加密sha256散列。在我的例子中,数据是base64(header)+“+base64(body)。这是我的密码: static String certificate = "MIIDBjCCAe4CCQDmPif23IJerzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQ

我试图通过验证JWT令牌的签名来验证它。但在验证过程中,我发现了一个错误

java.security.SignatureException:签名长度不正确:Get 342,但预期是256

。我假设签名是数据的加密
sha256
散列。在我的例子中,数据是base64(header)+“+base64(body)。这是我的密码:

static String certificate = "MIIDBjCCAe4CCQDmPif23IJerzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTE1MDkyMjA3MDkwMFoXDTE2MDkyMTA3MDkwMFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALYjKc8pLFkAa45j6w6PHsroe7ijOCfhZmVtMCvZ8lINaP9mR8irOJHpLdJs4vpbxEZMqqLMhKjO7iUmXBmml37QRlJXY6f25essPkTdUmhiIrU/rIrZrCanvegXUHkvf4xvOQ1BTx/p5b1iIq3Wrk5Fox3pMigzqYhk4YuiJho8uabC9zyecmS3zIoRgwx+Vacel/ZW6r6YOlB6mblN9IvasvqWgDalegmMKOIZvwkpo/3mfzcGi5haWZZ3ufUqQjb4B7raJmfyrLnwi6XI9UzzGc04pCfIAsxTb5yM8cJQcJ/5VHF3h21eFJdZKyD2210gSq7/Y8Oda0dDXQchmFcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAmBm84PfwOe5sGemT9D4ImIYWp/1xrV6b0zeaDZ6Yi7sz9R3VKjfnAxUVOHA7GlMi8xHHdDu7VhVhAWyFCvITdG00K18xJuKap1bwzw3kr70lLQaFahV+zaWKfWAfV34tots3G/hMqdOv0a+I/5t/T7oKPCmm/IfCVKdC1tGbTji+hxVLpaAkn60RFNzLKGFwtSxv9ObxR5Hn88+wV48VAcEnwcUk2DjBi1fW6jnMcNJbVd+/oKBOwj7UK2Lk10Qaeet8KKh5fFKEpgx7D4ITwer0G/Je1NMv1/lfNzpKlTKoBureF5C6B+rJIesQ/dAfg6H/ggxbgVMuo6imIPVvrg==";
static String signedData = "Z5MwwjtXdypMQGNwmNNuCVmRcDVT24EgtwoDWalF4icxwz7jyB99Yg3262D7OsERewv4cOfdEz3bbOF-iG7YWXeSC9YZeO1tGapqlc8FRtAergSUZC7BcbFEx75MfSy7qLWYTOfdpJesQ23rOzjF7KdrAMJC_Y0T_r6RuBcZVyfT4P55kICETYyv7bBDXc9V8BJUf-QHDu6DaH7u6PSyeOmdzFInI_LwySnMlr3VahoUfUpJmauU8yHQUnFakJBgrMBe1Au9tS-HxtDVnHmoHQw8xGXsVQnEOa1aPAcVWy0v7hILUSmWNAG3IZ0JwUztQitgtnTTzXDszUxTbJ4YlQ";

static String data = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiJodHRwczovL2NpdHJpeHAuY29tOjg0NDMvIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvZGQ5YjZhM2UtMjlkMS00MjU0LWE3NDYtZTAyOTQxNDQ0NTE3LyIsImlhdCI6MTQ0MjYyNjA0NSwibmJmIjoxNDQyNjI2MDQ1LCJleHAiOjE0NDI2Mjk5NDUsInZlciI6IjEuMCIsInRpZCI6ImRkOWI2YTNlLTI5ZDEtNDI1NC1hNzQ2LWUwMjk0MTQ0NDUxNyIsIm9pZCI6ImJkZDNmZDAyLTEyMzMtNGMxOC05NTRmLWJkNGFjMWYzOWU5OSIsInVwbiI6InNwQGNpdHJpeHAuY29tIiwic3ViIjoieUFfZTFzMmFOeFdvR3NSNzhfVWNYZkk5dERlYUM0QUozdXFZQXFDdllSbyIsImdpdmVuX25hbWUiOiJzIiwiZmFtaWx5X25hbWUiOiJwIiwibmFtZSI6InNwIiwiYW1yIjpbInB3ZCIsInJzYSJdLCJ1bmlxdWVfbmFtZSI6InNwQGNpdHJpeHAuY29tIiwiYXBwaWQiOiIyOWQ5ZWQ5OC1hNDY5LTQ1MzYtYWRlMi1mOTgxYmMxZDYwNWUiLCJhcHBpZGFjciI6IjAiLCJzY3AiOiJtZG1fZGVsZWdhdGlvbiIsImFjciI6IjEiLCJpcGFkZHIiOiI2My4xMTAuNTEuMTEiLCJkZXZpY2VpZCI6ImQyNzU3NzY0LWFiOTEtNDBiMS05MmM2LTViOWE4MWYxODNiYyJ9";

public static void main(String[] args) throws UnsupportedEncodingException {
    // TODO Auto-generated method stub
    String certString = "-----BEGIN CERTIFICATE-----\r\n" + certificate + "\r\n-----END CERTIFICATE-----";
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        CertificateFactory cf;
        try {
            cf = CertificateFactory.getInstance("X.509");
            InputStream stream = new ByteArrayInputStream(certString.getBytes()); //StandardCharsets.UTF_8
            java.security.cert.Certificate cert = cf.generateCertificate(stream);
            PublicKey pk = cert.getPublicKey();


            //verifying content with signature and content :
            Signature sig = Signature.getInstance("SHA256withRSA");
            sig.initVerify( pk );
            sig.update(data.getBytes());

            Boolean ret = sig.verify(signedData.getBytes());
        } catch (CertificateException | SignatureException | NoSuchAlgorithmException |  InvalidKeyException e) {
            e.printStackTrace();
        }

JWT的签名部分是base64url编码的(),因此您需要在验证之前对其进行正确解码

替换行
Boolean ret=sig.verify(signedData.getBytes())使用类似以下内容(使用Apache Commons Codec中的Base64解码器)

JWT上的签名应该可以为您验证

话虽如此,我还是非常推荐使用库进行JWT处理。一个像样的库可以为您处理类似的内容,还可以提供更多的JWT功能

例如,在从证书中获取公钥后,以下使用可以替换问题中代码中的内容。这不仅验证了规范中的签名,而且还验证了JWT中的声明,以确保其仍然有效、已发布给您等等

 JwtConsumer jwtConsumer = new JwtConsumerBuilder()
    .setVerificationKey(pk)
    .setRequireExpirationTime()
    .setExpectedAudience("https://citrixp.com:8443/")
    .setExpectedIssuer("https://sts.windows.net/dd9b6a3e-29d1-4254-a746-e02941444517/")
    .build();

 JwtClaims claims = jwtConsumer.processToClaims(data + "." + signedData);

 System.out.println("Subject: " + claims.getSubject());
 System.out.println("UPN: " + claims.getStringClaimValue("upn"));  // or whatever, etc....
该JWT已过期几天,因此
processToClaims
将抛出一个异常,这正是您想要的。您可以在构建
JwtConsumer
时添加
.setEvaluationTime(NumericDate.fromSeconds(1442626055))
以使其在给定的JWT下工作

 JwtConsumer jwtConsumer = new JwtConsumerBuilder()
    .setVerificationKey(pk)
    .setRequireExpirationTime()
    .setExpectedAudience("https://citrixp.com:8443/")
    .setExpectedIssuer("https://sts.windows.net/dd9b6a3e-29d1-4254-a746-e02941444517/")
    .build();

 JwtClaims claims = jwtConsumer.processToClaims(data + "." + signedData);

 System.out.println("Subject: " + claims.getSubject());
 System.out.println("UPN: " + claims.getStringClaimValue("upn"));  // or whatever, etc....