【问题标题】:JWT invalid signatureJWT 无效签名
【发布时间】:2016-12-29 11:42:14
【问题描述】:

我正在尝试使用 json Web 令牌开发我的应用程序。我决定使用 jjwt 但它不起作用。我有以下sn-p

Jwts.parser()
        .setSigningKey(secretKey)
        .parseClaimsJws(token)
        .getBody()

总是抛出异常。

我尝试使用以下代码生成令牌

String compactJws = Jwts.builder()
            .setSubject("Joe")
            .signWith(SignatureAlgorithm.HS256, "secret")
            .compact();

当我将这个令牌粘贴到这里https://jwt.io/ 时,我得到了它无效的信息。怎么了?

【问题讨论】:

标签: java jwt


【解决方案1】:

我认为您在 * .setSigningKey(secretKey) * 上做错了什么。 这是完整的代码,说明了如何使用 JWT 验证令牌。

package com.brajesh.test;
import java.security.Key;
import java.util.Date;
import java.util.UUID;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JwtTokenDemo {

    private String secretKey;

    public static void main(String[] args) {
        JwtTokenDemo jwtTokenDemo = new JwtTokenDemo();
        String tokens = jwtTokenDemo.createJWT("123", "thriev.com", "brajesh@gmail.com", 12999L);
        System.out.println("tokens : "+tokens);

        System.out.println("========AFTER============");
        jwtTokenDemo.parseJWT(tokens);
    }


    //Sample method to validate and read the JWT
    private void parseJWT(String jwt) {
    //This line will throw an exception if it is not a signed JWS (as expected)
    Claims claims = Jwts.parser()         
       .setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
       .parseClaimsJws(jwt).getBody();
        System.out.println("ID: " + claims.getId());
        System.out.println("Subject: " + claims.getSubject());
        System.out.println("Issuer: " + claims.getIssuer());
        System.out.println("Expiration: " + claims.getExpiration());
    }
/**
 * 
 * @param id
 * @param issuer
 * @param subject
 * @param ttlMillis
 * @return
 */
private String createJWT(String id, String issuer, String subject, long ttlMillis) {

  //The JWT signature algorithm we will be using to sign the token
  SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

  long nowMillis = System.currentTimeMillis();
  Date now = new Date(nowMillis);
  String keys = UUID.randomUUID().toString();
  System.out.println(keys);
  this.secretKey = keys;

  byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(keys);
  Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());


  JwtBuilder builder = Jwts.builder().setId(id)
                              .setIssuedAt(now)
                              .setSubject(subject)
                              .setIssuer(issuer)
                              .signWith(signatureAlgorithm, signingKey);

  if (ttlMillis >= 0) {
  long expMillis = nowMillis + ttlMillis;
      Date exp = new Date(expMillis);
      builder.setExpiration(exp);
  }
  return builder.compact();
}
}

【讨论】:

    【解决方案2】:

    您在signWith 方法中传递了一个纯文本密钥,这就是问题所在;

    根据JJWT源码:

    /** 
    331      * Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS. 
    332      * 
    333      * <p>This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting 
    334      * byte array is used to invoke {@link #signWith(SignatureAlgorithm, byte[])}.</p> 
    335      * 
    336      * @param alg                    the JWS algorithm to use to digitally sign the JWT, thereby producing a JWS. 
    337      * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signing key to use to digitally sign the 
    338      *                               JWT. 
    339      * @return the builder for method chaining. 
    340      */ 
    341     JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey); 
    342 
    
    343     /** 
    344      * Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS. 
    345      * 
    346      * @param alg the JWS algorithm to use to digitally sign the JWT, thereby producing a JWS. 
    347      * @param key the algorithm-specific signing key to use to digitally sign the JWT. 
    348      * @return the builder for method chaining. 
    349      */ 
    350     JwtBuilder signWith(SignatureAlgorithm alg, Key key); 
    

    传递一个包含密钥的 base-64 字符串,或者声明一个 Key 对象并传递相关信息来构建它。 比如例子中:

    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("c2VjcmV0");//this has to be base-64 encoded, it reads 'secret' if we de-encoded it
    Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
    
      //Let's set the JWT Claims
    JwtBuilder builder = Jwts.builder().setId(id)
                                    .setIssuedAt(now)
                                    .setSubject(subject)
                                    .setIssuer(issuer)
                                    .signWith(signatureAlgorithm, signingKey);
    

    【讨论】:

      猜你喜欢
      • 2020-01-21
      • 2018-01-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 2019-08-04
      • 2018-05-08
      • 2019-01-02
      • 2017-05-30
      相关资源
      最近更新 更多