java token自定义实现
import com.example.newsmanager.model.Token;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TokenUtil {
public static final String TOKEN_NAME = "token";
private TokenUtil() {}
public static void addToken(HttpServletResponse response, String data) {
Token token = new Token(data);
Cookie cookie = new Cookie(TOKEN_NAME,token.toString());
cookie.setMaxAge((int) (token.getDuration() / 1000 - 10));
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
public static boolean verify(HttpServletRequest request) {
Token token = getTokenFromCookie(request);
return token != null && token.verify();
}
public static boolean verify(HttpServletRequest request, boolean head) {
if (!verify(request)) {
return false;
}else if(head) {
Token token = getTokenFromHeader(request);
return token != null && token.verify();
}else {
return true;
}
}
private static Token getTokenFromCookie(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (TOKEN_NAME.equals(cookie.getName())) {
return Token.valueOf(cookie.getValue());
}
}
}
return null;
}
private static Token getTokenFromHeader(HttpServletRequest request) {
String tokenStr = request.getHeader(TOKEN_NAME);
return Token.valueOf(tokenStr);
}
public static void deleteToken(HttpServletResponse response) {
Cookie cookie = new Cookie(TOKEN_NAME,"");
cookie.setMaxAge(0);
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
}
import com.example.newsmanager.props.TokenProps;
import com.example.newsmanager.util.RSAUtil;
import lombok.Data;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@Data
public class Token {
private String data;
private long timestamp = System.currentTimeMillis();
private long duration = 43200000L;//one day
private String sign;
public Token(String data, long timestamp, long duration, String sign) {
this.data = data;
this.timestamp = timestamp;
this.duration = duration;
this.sign = sign;
}
public Token(String data, long timestamp, long duration) {
this.data = data;
this.timestamp = timestamp;
this.duration = duration;
initSign();
}
public Token(String data) {
this.data = data;
initSign();
}
public Token(String data, long duration) {
this.data = data;
this.duration = duration;
initSign();
}
private void initSign() {
try {
this.sign = RSAUtil.sign(data+","+timestamp+","+duration, TokenProps.getPriKey());
}catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return Base64.getEncoder().encodeToString((data+"\n"+timestamp+"\n"+duration+"\n"+sign).getBytes(StandardCharsets.UTF_8));
}
public boolean verify() {
boolean flag = false;
try {
flag = RSAUtil.verify(data+","+timestamp+","+duration, TokenProps.getPubKey(),sign);
if (flag) {
long curTime = System.currentTimeMillis();
flag = timestamp + duration > curTime;
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
public static Token valueOf(String token) {
if (token != null && token .length() > 0) {
try {
byte[] bytes = Base64.getDecoder().decode(token);
String data = new String(bytes);
String[] arr = data.split("\n");
return new Token(arr[0],Long.parseLong(arr[1]),Long.parseLong(arr[2]),arr[3]);
}catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtil {
private static final int KEY_SIZE = 512;
private static final String SIGN_TYPE = "MD5withRSA";
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE >> 3;
private static final int MAX_ENCRYPT_BLOCK = MAX_DECRYPT_BLOCK - 11;
public static void generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Key publicKey = keyPair.getPublic();
Key privateKey = keyPair.getPrivate();
String publicKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String privateKeyStr = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("pub:" + publicKeyStr);
System.out.println("pri:" + privateKeyStr);
}
public static PrivateKey getPrivateKey(String privateKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.getDecoder().decode(privateKey.getBytes());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
return keyFactory.generatePrivate(keySpec);
}
public static PublicKey getPublicKey(String publicKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.getDecoder().decode(publicKey.getBytes());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
return keyFactory.generatePublic(keySpec);
}
public static String encrypt(String data, String pubKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(pubKey));
int inputLen = data.getBytes().length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
while (inputLen - offset > 0) {
if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64.getEncoder().encodeToString(encryptedData);
}
public static String decrypt(String data, String priKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(priKey));
byte[] dataBytes = Base64.getDecoder().decode(data);
int inputLen = dataBytes.length;
try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
int offset = 0;
byte[] cache;
int i = 0;
while (inputLen - offset > 0) {
if (inputLen - offset > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_DECRYPT_BLOCK;
}
return out.toString("UTF-8");
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String sign(String data, String priKey) throws Exception {
Signature signature = Signature.getInstance(SIGN_TYPE);
signature.initSign(getPrivateKey(priKey));
signature.update(data.getBytes());
return Base64.getEncoder().encodeToString(signature.sign());
}
public static boolean verify(String srcData, String pubKey, String sign) throws Exception {
Signature signature = Signature.getInstance(SIGN_TYPE);
signature.initVerify(getPublicKey(pubKey));
signature.update(srcData.getBytes());
return signature.verify(Base64.getDecoder().decode(sign));
}
}
不积跬步无以至千里