-
-
Save alsritter/2b79b3518ca52570b52cff72a6473fc0 to your computer and use it in GitHub Desktop.
用来测试 SpringSercurity RSA 服务的那个,原文地址:https://blog.csdn.net/weixin_43461520/article/details/107941983
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.robod.utils; | |
import com.fasterxml.jackson.core.JsonProcessingException; | |
import com.fasterxml.jackson.core.type.TypeReference; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.IOException; | |
import java.util.List; | |
import java.util.Map; | |
public class JsonUtils { | |
public static final ObjectMapper mapper = new ObjectMapper(); | |
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class); | |
public static String toString(Object obj) { | |
if (obj == null) { | |
return null; | |
} | |
if (obj.getClass() == String.class) { | |
return (String) obj; | |
} | |
try { | |
return mapper.writeValueAsString(obj); | |
} catch (JsonProcessingException e) { | |
logger.error("json序列化出错:" + obj, e); | |
return null; | |
} | |
} | |
public static <T> T toBean(String json, Class<T> tClass) { | |
try { | |
return mapper.readValue(json, tClass); | |
} catch (IOException e) { | |
logger.error("json解析出错:" + json, e); | |
return null; | |
} | |
} | |
public static <E> List<E> toList(String json, Class<E> eClass) { | |
try { | |
return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass)); | |
} catch (IOException e) { | |
logger.error("json解析出错:" + json, e); | |
return null; | |
} | |
} | |
public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) { | |
try { | |
return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass)); | |
} catch (IOException e) { | |
logger.error("json解析出错:" + json, e); | |
return null; | |
} | |
} | |
public static <T> T nativeRead(String json, TypeReference<T> type) { | |
try { | |
return mapper.readValue(json, type); | |
} catch (IOException e) { | |
logger.error("json解析出错:" + json, e); | |
return null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.robod.utils; | |
import com.robod.entity.Payload; | |
import io.jsonwebtoken.Claims; | |
import io.jsonwebtoken.Jws; | |
import io.jsonwebtoken.Jwts; | |
import io.jsonwebtoken.SignatureAlgorithm; | |
import org.joda.time.DateTime; | |
import java.security.PrivateKey; | |
import java.security.PublicKey; | |
import java.util.Base64; | |
import java.util.UUID; | |
/** | |
* 生成token以及校验token相关方法 | |
*/ | |
public class JwtUtils { | |
private static final String JWT_PAYLOAD_USER_KEY = "user"; | |
/** | |
* 私钥加密token | |
* | |
* @param userInfo 载荷中的数据 | |
* @param privateKey 私钥 | |
* @param expire 过期时间,单位分钟 | |
* @return JWT | |
*/ | |
public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) { | |
return Jwts.builder() | |
.claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)) | |
.setId(createJTI()) | |
.setExpiration(DateTime.now().plusMinutes(expire).toDate()) | |
.signWith(privateKey, SignatureAlgorithm.RS256) | |
.compact(); | |
} | |
/** | |
* 私钥加密token | |
* | |
* @param userInfo 载荷中的数据 | |
* @param privateKey 私钥 | |
* @param expire 过期时间,单位秒 | |
* @return JWT | |
*/ | |
public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) { | |
return Jwts.builder() | |
.claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)) | |
.setId(createJTI()) | |
.setExpiration(DateTime.now().plusSeconds(expire).toDate()) | |
.signWith(privateKey, SignatureAlgorithm.RS256) | |
.compact(); | |
} | |
/** | |
* 公钥解析token | |
* | |
* @param token 用户请求中的token | |
* @param publicKey 公钥 | |
* @return Jws<Claims> | |
*/ | |
private static Jws<Claims> parserToken(String token, PublicKey publicKey) { | |
return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token); | |
} | |
private static String createJTI() { | |
return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes())); | |
} | |
/** | |
* 获取token中的用户信息 | |
* | |
* @param token 用户请求中的令牌 | |
* @param publicKey 公钥 | |
* @return 用户信息 | |
*/ | |
public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) { | |
Jws<Claims> claimsJws = parserToken(token, publicKey); | |
Claims body = claimsJws.getBody(); | |
Payload<T> claims = new Payload<>(); | |
claims.setId(body.getId()); | |
claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType)); | |
claims.setExpiration(body.getExpiration()); | |
return claims; | |
} | |
/** | |
* 获取token中的载荷信息 | |
* | |
* @param token 用户请求中的令牌 | |
* @param publicKey 公钥 | |
* @return 用户信息 | |
*/ | |
public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) { | |
Jws<Claims> claimsJws = parserToken(token, publicKey); | |
Claims body = claimsJws.getBody(); | |
Payload<T> claims = new Payload<>(); | |
claims.setId(body.getId()); | |
claims.setExpiration(body.getExpiration()); | |
return claims; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.robod.entity; | |
import lombok.Data; | |
import java.util.Date; | |
/** | |
* 负荷实体类 | |
* 为了方便后期获取token中的用户信息,将token中载荷部分单独封装成一个对象 | |
*/ | |
@Data | |
public class Payload<T> { | |
private String id; | |
private T userInfo; | |
private Date expiration; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.robod.utils; | |
import java.io.File; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.security.*; | |
import java.security.spec.InvalidKeySpecException; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import java.util.Base64; | |
public class RsaUtils { | |
private static final int DEFAULT_KEY_SIZE = 2048; | |
/** | |
* 从文件中读取公钥 | |
* | |
* @param filename 公钥保存路径,相对于classpath | |
* @return 公钥对象 | |
* @throws Exception | |
*/ | |
public static PublicKey getPublicKey(String filename) throws Exception { | |
byte[] bytes = readFile(filename); | |
return getPublicKey(bytes); | |
} | |
/** | |
* 从文件中读取密钥 | |
* | |
* @param filename 私钥保存路径,相对于classpath | |
* @return 私钥对象 | |
* @throws Exception | |
*/ | |
public static PrivateKey getPrivateKey(String filename) throws Exception { | |
byte[] bytes = readFile(filename); | |
return getPrivateKey(bytes); | |
} | |
/** | |
* 获取公钥 | |
* | |
* @param bytes 公钥的字节形式 | |
* @return | |
* @throws Exception | |
*/ | |
private static PublicKey getPublicKey(byte[] bytes) throws Exception { | |
bytes = Base64.getDecoder().decode(bytes); | |
X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes); | |
KeyFactory factory = KeyFactory.getInstance("RSA"); | |
return factory.generatePublic(spec); | |
} | |
/** | |
* 获取密钥 | |
* | |
* @param bytes 私钥的字节形式 | |
* @return | |
* @throws Exception | |
*/ | |
private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException { | |
bytes = Base64.getDecoder().decode(bytes); | |
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes); | |
KeyFactory factory = KeyFactory.getInstance("RSA"); | |
return factory.generatePrivate(spec); | |
} | |
/** | |
* 根据密文,生存rsa公钥和私钥,并写入指定文件 | |
* | |
* @param publicKeyFilename 公钥文件路径 | |
* @param privateKeyFilename 私钥文件路径 | |
* @param secret 生成密钥的密文 | |
*/ | |
public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception { | |
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); | |
SecureRandom secureRandom = new SecureRandom(secret.getBytes()); | |
keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom); | |
KeyPair keyPair = keyPairGenerator.genKeyPair(); | |
// 获取公钥并写出 | |
byte[] publicKeyBytes = keyPair.getPublic().getEncoded(); | |
publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes); | |
writeFile(publicKeyFilename, publicKeyBytes); | |
// 获取私钥并写出 | |
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); | |
privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes); | |
writeFile(privateKeyFilename, privateKeyBytes); | |
} | |
private static byte[] readFile(String fileName) throws Exception { | |
return Files.readAllBytes(new File(fileName).toPath()); | |
} | |
private static void writeFile(String destPath, byte[] bytes) throws IOException { | |
File dest = new File(destPath); | |
if (!dest.exists()) { | |
dest.createNewFile(); | |
} | |
Files.write(dest.toPath(), bytes); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment