Java验证jwt token
2024-08-27 14:33:00
https://jwt.io/
RS256加密JWT生成、验证
https://blog.csdn.net/u011411069/article/details/79966226
How to load public certificate from pem file..?
https://www.howtobuildsoftware.com/index.php/how-do/ciLJ/java-ssl-cryptography-bouncycastle-public-key-how-to-load-public-certificate-from-pem-file
1.HS256对称加密
package jwt; import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.Vector;
import java.util.Map; import sun.misc.BASE64Decoder; import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT; public class JWTValidator {
private static String JWT_Type = "JWT"; protected boolean validated;
protected Object[] claims; public JWTValidator() {
setValidated(false);
setClaims(null);
}
public String Generate(String secret, String issuer, String audience, String subject){
try {
Algorithm algorithm = Algorithm.HMAC256(secret); // HS256
String token = JWT.create()
.withIssuer(issuer)
.withAudience(audience)
.withSubject(subject)
.sign(algorithm);
System.out.println(token);
return token;
} catch (Exception exception){
//UTF-8 encoding not supported
return "";
}
} public void Validate(String token, String secret, String issuer, String audience, String subject) {
DecodedJWT jwt = null;
setValidated(false); if (token == null || secret == null || issuer == null || audience == null || subject == null)
return; try {
jwt = JWT.require(Algorithm.HMAC256(secret.getBytes())).build().verify(token);
} catch (JWTVerificationException e) {
return;
} if (jwt == null || jwt.getType() == null || !jwt.getType().contentEquals(JWT_Type))
return; if (!jwt.getIssuer().contentEquals(issuer) ||
!jwt.getAudience().contains(audience) ||
!jwt.getSubject().contentEquals(subject))
return; Date now = new Date(); if ((jwt.getNotBefore() != null && jwt.getNotBefore().after(now)) ||
(jwt.getExpiresAt() != null && jwt.getExpiresAt().before(now)))
return; setValidated(true); Map<String, Claim> claimsMap = jwt.getClaims();
Vector<Claim> claimsVector = new Vector<Claim>(); if (claimsMap != null) {
for (Map.Entry<String, Claim> entry : claimsMap.entrySet()) {
String key = entry.getKey();
if (key != null && !key.matches("aud|sub|iss|exp|iat")) {
//claimsVector.add(new Claim(key, entry.getValue().asString()));
}
}
} setClaims(claimsVector.isEmpty() ? null : claimsVector.toArray());
} public boolean isValidated() { return validated; }
public void setValidated(boolean val) { validated = val; } public Object[] getClaims() { return claims; }
public void setClaims(Object[] val) { claims = (val == null ? new Object[0] : val); }
}
2.RS256不对称加密,需要用public cert来验证
package jwt; import junit.framework.TestCase;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue; import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.UUID; public class JWTValidatorForRSA extends TestCase{ public void testCreateToken() throws IOException {
System.out.println(createToken());
} public void testVerifyToken() throws Exception {
String token = createToken();
System.out.println(token); String pkeyPath = "D:\\temp\\idsrv4.crt";
JwtClaims jwtClaims = verifyToken(token,pkeyPath);
System.out.println(jwtClaims.getClaimValue("name"));
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(jwtClaims.getIssuedAt().getValueInMillis()));
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(jwtClaims.getExpirationTime().getValueInMillis()));
} /**
* 生成jwt,SHA256加密
* @return
* @throws IOException
*/
public String createToken() throws IOException {
String privateKeyPath = "D:\\temp\\idsrv4.key";
PrivateKey privateKey = getPrivateKey(getStringFromFile(privateKeyPath));
final JwtClaims claims = new JwtClaims();
claims.setClaim("name", "jack");
claims.setSubject("a@a.com");
claims.setAudience("test");//用于验证签名是否合法,验证方必须包含这些内容才验证通过
claims.setExpirationTimeMinutesInTheFuture(-1); // 60*24*30);
claims.setIssuedAtToNow(); // Generate the payload
final JsonWebSignature jws = new JsonWebSignature();
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
jws.setPayload(claims.toJson());
jws.setKeyIdHeaderValue(UUID.randomUUID().toString()); // Sign using the private key
jws.setKey(privateKey);
try {
return jws.getCompactSerialization();
} catch (JoseException e) {
return null;
}
} /**
* 验证jwt
* @param token
* @return
* @throws Exception
*/
public JwtClaims verifyToken(String token,String publicKeyPath) throws Exception { try {
PublicKey publicKey = getPublicKey(publicKeyPath); JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setVerificationKey(publicKey)
.setExpectedAudience("test")//用于验证签名是否合法,可以设置多个,且可设置必须存在项,如果jwt中不包含这些内容则不通过
.build(); return jwtConsumer.processToClaims(token);
} catch (Exception e) {
throw new RuntimeException(e);
}
} private String getStringFromFile(String filePath) throws IOException {
// 生成方法:安装openssl,执行 openssl genrsa -out private.pem 2048
return IOUtils.toString(new FileInputStream(filePath));
} /**
* 获取PublicKey对象
* @param publicKeyBase64
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws CertificateException
* @throws FileNotFoundException
*/
private PublicKey getPublicKey(String publicKeyPath) throws NoSuchAlgorithmException, InvalidKeySpecException, CertificateException, FileNotFoundException {
/* Not work : data isn't an object ID (tag = 2)
String pem = publicKeyBase64
.replaceAll("\\-*BEGIN.*CERTIFICATE\\-*", "")
.replaceAll("\\-*END.*CERTIFICATE\\-*", "");
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
System.out.println(pem); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(pem));
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
*/ CertificateFactory fact = CertificateFactory.getInstance("X.509");
FileInputStream is = new FileInputStream (publicKeyPath);
X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
PublicKey publicKey = cer.getPublicKey(); System.out.println(publicKey); return publicKey;
} /**
* 获取PrivateKey对象
* @param privateKeyBase64
* @return
*/
private PrivateKey getPrivateKey(String privateKeyBase64) {
String privKeyPEM = privateKeyBase64
.replaceAll("\\-*BEGIN.*KEY\\-*", "")
.replaceAll("\\-*END.*KEY\\-*", ""); // Base64 decode the data
byte[] encoded = Base64.decodeBase64(privKeyPEM); try {
DerInputStream derReader = new DerInputStream(encoded);
DerValue[] seq = derReader.getSequence(0); if (seq.length < 9) {
throw new GeneralSecurityException("Could not read private key");
} // skip version seq[0];
BigInteger modulus = seq[1].getBigInteger();
BigInteger publicExp = seq[2].getBigInteger();
BigInteger privateExp = seq[3].getBigInteger();
BigInteger primeP = seq[4].getBigInteger();
BigInteger primeQ = seq[5].getBigInteger();
BigInteger expP = seq[6].getBigInteger();
BigInteger expQ = seq[7].getBigInteger();
BigInteger crtCoeff = seq[8].getBigInteger(); RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp,
primeP, primeQ, expP, expQ, crtCoeff); KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePrivate(keySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
最新文章
- awk sed 总结
- String使用机制及string.equals()和==的区别(转)
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)
- Modular Query
- [原创]java WEB学习笔记51:国际化 概述,API 之 locale类,dataFormat类,numberFormat类, MessageFormat类,ResourceBundle 类
- 第二百五十六天 how can I 坚持
- Commons JXPath - DOM/JDOM Document Access
- spring mvc DispatcherServlet详解之一--request通过HandlerMaping获取控制器Controller过程
- dlopen函数详解
- chrome console的使用 : 异常和错误的处理 – Break易站
- vue开发中regeneratorRuntime is not defined
- Windows下return,exit和ExitProcess的区别和分析
- Java容器解析系列(6) Queue Deque AbstractQueue 详解
- informix数据库触发器的写法
- HTTP redirect 重定向到 HTTPS
- Dacapao 实验集(9.12 版本) 能不能给个网址?【内存分析实验】
- laravel的函数asset()、url()
- Android开发之ListView条目批量选择删除
- (C++)浅谈using namespace std
- 008.C++类改写模板类
热门文章
- Python如何进行有背景图片的界面跳转
- Mysql系列(六)—— MySQL索引介绍
- 你读过的最好的 C++ 开源代码是什么?
- Python变量问题:命名、类型、赋值
- mysql提示The server quit without updating PID file /usr/local/mysql/data/localhost.localdomain.pid
- C#控制操控操作多个UVC摄像头设备
- 第一阶段:Java基础 1.JAVA开发介绍---6. Java基本数据类型
- 2019 中兴java面试笔试题 (含面试题解析)
- 【开发笔记】-Ubuntu环境命令初始化
- Python - 实现矩阵转置