其他工具
大约 3 分钟
其他工具
1. jjwt
- jjwt
是一个用于创建和验证JSON Web Token(JWT)的库 JWT是一个基于json的网络令牌,用来在不同的系统和访问之间安全地传递信息JWT由三部分构成<header>.<payload>.<signature>,用.分隔header:主要包含alg和typ两个字段,分别用于指定JWT的签名算法和类型payload:用于存储需要传递的信息signature:用于验证JWT的完整性和真实性,即签名,这里的值是通过特定算法对header和payload计算生成的
JWT的header和payload的格式通常为json,并通过Base64进行编码,使用编码完成后的<header>.<payload>部分生成signature- 内容未进行加密,应该避免存储敏感信息
使用
添加依赖,见readme
创建一个
JWT使用
Jwt.builder()创建一个JWT生成器设置一些可选的头部参数
设置一些负载
生成
signature最后使用
build()构建完成可选压缩
compact()Date expiration = new Date(System.currentTimeMillis() + 3600_000); byte[] content = "Hello World".getBytes(StandardCharsets.UTF_8); SecretKey key = Jwts.SIG.HS256.key().build(); // 如果是非对称,私钥加密 PublicKey key = Jwts.SIG.RS256.keyPair().build().getPublic(); // 创建一个 JWT 生成器 String jwt = Jwt.builder() // 设置头部参数,如果不需要,可以忽略 .header() // 设置使用了哪个密钥 id .keyId("aKeyId") // 表示一个 X.509 公钥证书的 URL,接收方可以通过这个 URL 获取公钥 .x509Url("https://example.com/public.pem") // 添加自定义键值对 .add("someName", "anyValue") // 通过 and 继续后续的负载操作 .and() // 一些符合 JWT 规范的负载参数 .issuer("me") // 签发者 .subject("you") // 主题 .audience("you") // 接收者 .expiresAt(expiration) // 过期时间 .notBefore(new Date()) // 生效时间 .issuedAt(new Date()) // 签发时间 .id("aJwtId") // JWT 的 id // 添加负载 .claim("userId", "anyValue") // 如果不需要 json,使用自定义类型的负载(不能和 claim 同时设置) // .content(content, "text/plain") // 设置签名 .signWith(key) // 构建 JWT .build();
验证
JWT使用
Jwts.parser()创建一个JWT解析器通过公钥验证
JWT获取
JWT的负载PublicKey key = Jwts.SIG.RS256.keyPair().build().getPublic(); Jws<Claims> parsed = Jwts.parser().verifyWith(testKey) // 借助断言判断 assert "joe".equals(parsed.getPayload().getSubject()); assert "me".equals(parsed.getPayload().getIssuer()); // 获取特定的负载 String userId = parsed.getPayload().get("userId", String.class); // 获取头字段 String kid = parsed.getHeader().getKeyId();
固定密钥
对于非对称加密,密钥应该被固定,确保所有人都能通过公钥解密
对于对称加密,虽然密钥可以不固定,但不固定密钥不方便重启恢复
// 生成密钥对 KeyPair keyPair = Jwts.SIG.ES256.keyPair().build(); // 解析成 base64 String privateKeyBase64 = Encoders.BASE64.encode(keyPair.getPrivate().getEncoded()); String publicKeyBase64 = Encoders.BASE64.encode(keyPair.getPublic().getEncoded()); // 恢复时需使用 base64 解码得到 byte[] byte[] bytes = Decoders.BASE64.decode(privateKeyBase64); // 使用对应的密钥算法恢复密钥 // 比如 ES256 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes1); PrivateKey pk = KeyFactory.getInstance("EC").generatePrivate(keySpec); // 恢复公钥也一样 // byte[] bytes = Decoders.BASE64.decode(publicKeyBase64); // X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); // PublicKey pk = KeyFactory.getInstance("EC").generatePublic(keySpec);
