JWT无效签名

时间:2016-08-22 19:57:12

标签: java jwt

我正在尝试使用json web令牌开发我的应用程序。我决定使用jjwt,但它不起作用。我有一个以下代码段

    // Wrap the presented view controller's view in an intermediate hierarchy
    // that applies a shadow and rounded corners to the top-left and top-right
    // edges.  The final effect is built using three intermediate views.
    //
    // presentationWrapperView              <- shadow
    //   |- presentationRoundedCornerView   <- rounded corners (masksToBounds)
    //        |- presentedViewControllerWrapperView
    //             |- presentedViewControllerView (presentedViewController.view)
    //
    // SEE ALSO: The note in AAPLCustomPresentationSecondViewController.m.


    let presentationWrapperView = UIView(frame: frameOfPresentedViewInContainerView)
    presentationWrapperView.layer.shadowOpacity = 0.44
    presentationWrapperView.layer.shadowRadius = 13
    presentationWrapperView.layer.shadowOffset = CGSize(width: 0, height: -6)
    self.presentationWrappingView = presentationWrapperView

    // presentationRoundedCornerView is CORNER_RADIUS points taller than the
    // height of the presented view controller's view.  This is because
    // the cornerRadius is applied to all corners of the view.  Since the
    // effect calls for only the top two corners to be rounded we size
    // the view such that the bottom CORNER_RADIUS points lie below
    // the bottom edge of the screen.
    let presentationRoundedCornerView = UIView(frame: UIEdgeInsetsInsetRect(presentationWrapperView.bounds, UIEdgeInsets(top: 0, left: 0, bottom: -CORNER_RADIUS, right: 0)))
    presentationRoundedCornerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    presentationRoundedCornerView.layer.cornerRadius = CORNER_RADIUS
    presentationRoundedCornerView.layer.masksToBounds = true

    // To undo the extra height added to presentationRoundedCornerView,
    // presentedViewControllerWrapperView is inset by CORNER_RADIUS points.
    // This also matches the size of presentedViewControllerWrapperView's
    // bounds to the size of -frameOfPresentedViewInContainerView.
    let presentedViewControllerWrapperView = UIView(frame: UIEdgeInsetsInsetRect(presentationRoundedCornerView.bounds, UIEdgeInsets(top: 0, left: 0, bottom: CORNER_RADIUS, right: 0)))
    presentedViewControllerWrapperView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    let blurWrapperView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    blurWrapperView.autoresizingMask =  [.flexibleWidth, .flexibleHeight]
    blurWrapperView.frame = presentedViewControllerWrapperView.bounds

    // Add presentedViewControllerView -> presentedViewControllerWrapperView.
    presentedViewControllerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    presentedViewControllerView.frame = blurWrapperView.bounds
    blurWrapperView.contentView.addSubview(presentedViewControllerView)

    presentedViewControllerWrapperView.addSubview(blurWrapperView)
    // Add presentedViewControllerWrapperView -> presentationRoundedCornerView.
    presentationRoundedCornerView.addSubview(presentedViewControllerWrapperView)

    // Add presentationRoundedCornerView -> presentationWrapperView.
    presentationWrapperView.addSubview(presentationRoundedCornerView)
总是抛出异常的

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

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

当我在此处粘贴此令牌https://jwt.io/时,我收到了无效的信息。有什么问题?

2 个答案:

答案 0 :(得分:0)

您在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);

答案 1 :(得分:0)

我认为你的* .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();
}
}