相关文章推荐
非常酷的葡萄  ·  C++: ...·  4 月前    · 
紧张的柠檬  ·  jQuery.Callbacks() ...·  1 年前    · 
酒量小的小刀  ·  Mysql Grant ...·  1 年前    · 
眉毛粗的水龙头  ·  file.readalltext out ...·  1 年前    · 

偶然的机会发现在参数相同情况下利用Python(pyjwt)生成的JWT和JAVA服务返回的不同:
Java依赖:

	 <dependency>
	     <groupId>io.jsonwebtoken</groupId>
	     <artifactId>jjwt</artifactId>
	     <version>0.9.1</version>
	 </dependency>

注意到Java中使用setHeader()setPayload()方法生成的token和Python中pyjwt的一致。

        .....// 此处省略n行
        JwtBuilder builder = Jwts.builder()
        		.setClaims(payload)
				// .setHeader(header)
				// .setPayload(payload) 
                .signWith(signatureAlgorithm, salt);
        return builder.compact();  //开始压缩为***.***.***格式的JWT

但使用setClaims()时无法达到与pyjwt的加密一致性,以下是setClaims的相关说明:

* Sets the JWT payload to be a JSON Claims instance populated by the specified name/value pairs. If you do not * want the JWT body to be JSON and instead want it to be a plaintext string, use the {@link #setPayload(String)} * method instead. * <p>The payload* and claims* properties are mutually exclusive - only one of the two may be used.</p> * @param claims the JWT claims to be set as the JWT body. * @return the builder for method chaining. JwtBuilder setClaims(Map<String, Object> claims);

至此略有眉目,Python应该是通过json.dumps()直接序列化为plaintext string的。
后面通过对解密过程进行追踪,发现Java中对JWT的header部分做了个性化处理:

    public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) {
        Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty.");
        byte[] bytes = TextCodec.BASE64.decode(base64EncodedSecretKey);
        return signWith(alg, bytes);

其中的TextCodec.BASE64.decode(base64EncodedSecretKey);解密成bytes的操作与Python中base64.decodebytes()相对应;

从两个方面解决均可:

  • Java方面妥协:
    Java中使用setHeader()setPayload()方法进行加密;
  • Python方面妥协:
    Python中对salt进行处理
    j_salt = base64.decodebytes(salt.encode('utf-8'))
    
    之后再进行操作。例如:
    原来是这样:
    sign = base64.urlsafe_b64encode(hmac.new(salt, first_second.encode('utf-8'), hashlib.sha512).digest()).decode('utf-8').replace('=', '')
    修改为:
    sign = base64.urlsafe_b64encode(hmac.new(j_salt, first_second.encode('utf-8'), hashlib.sha512).digest()).decode('utf-8').replace( '=', '')
    最终的jwt为{header}.{payload}.{sign}
今天做解析JWT的时候出现了一个问题,就是通过setClaims设置的内容在解析中能够正常解析出来,但是通过类似内置的setSubject,setIssusAt这种设置的却没有被解析出来。原因是出现在生成jwt的阶段。 原来的代码: JwtBuilder builder = Jwts.builder() .signWith(SignatureAlgorithm.HS256,jwtConfig.getSecret()) .setIssued
在使用jwt生产token时,我们要封装信息在token中,而我就用了setClaims(),但是我的时间戳设置是在前面,导致校验token是否过期时一致获取不到。 生成token private static String getToken(String id){ Map<String, Object> claimMaps = new HashMap<>(); claimMaps.put("id",id); long current
jwt验证:主要验证上图的【签证】部分是否合法 应用举例:如 利用jwt生成一个加密的token,作为用户登录的令牌,当用户登录成功后,发给客户端,请求需要登录的资源机或者接口的时候,将token携带,后端验证token是否合法 【案例演示】 基于springboot项目演示 导入依赖: <dependency>
JWT(JSON Web Token)是一种用于认证和授权的开放标准,它是基于JSON的一种简洁、自包含的安全传输格式。而Java-JWT则是一个用Java语言实现的JWT库,它提供了创建、解析、验证JWT的API。 因此,JWT是一种标准,而Java-JWT是一个具体实现。Java-JWT库提供了一些方便的API,使得在Java应用程序中使用JWT更加容易,可以直接使用Java-JWT库中提供的API完成JWT的创建、解析和验证操作。
I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this Tensor 19371
I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this Tensor Runesia: 我只记得删虚拟环境,一个教程一个教程试。。。 受苦啊。。。 I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this Tensor qq_49239516: 表情包主要是复现别人代码,他用的TensorFlow I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this Tensor Runesia: 这种配环境的问题你隔两年问,是不可能问到的,我记得后来还是配出来了,,如果不是必须,还是推荐你配别的库,tensorflow 现在用的比较不是主流了。