1. AES
package com.cdp.drs.utils;
/**
* Created by kevinwyu@deloitte.com.cn
*/
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Random;
/**
* @Author kevinwyu@deloitte.com.cn
* @date 20/08/2021 16:10
* @description AES加密工具类
*/
@Service
public class AESUtil {
private static final Logger logger = LoggerFactory.getLogger(AESUtil.class);
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";//检查报告推荐的加密算法
public static final String DEFAULT_PUBLIC_KEY = "kLy1Xq7FbviCknul";
public static final String DEFAULT_IV = "kLy1Xq7FbviCknul";
public static void main(String[] args) {
//需要加密的内容,如mobile
String content = "8613788888888";
//获取一个16位的随机公钥,该算法key只能为16位。
String publicKey = getGUID();
System.out.println("publicKey:" + publicKey);
//使用CBC模式,需要一个向量iv,增加加密算法的强度,简单起见这里指定为与公钥相同,该iv也只能为16位
String iv = publicKey;
//打印加密后的字符串
String contents = encrypt(content, publicKey, iv);
System.out.println("加密后内容:" + contents);
//打印解密后的字符串
content = decrypt(contents, publicKey, iv);
System.out.println("解密后内容:" + content);
// 使用默认的公钥和IV 加解密
/* System.out.println(defaultEncrypt(content));
System.out.println(defaultDecrypt(defaultEncrypt(content)));*/
}
/**
* 生成16位不重复的随机数,含数字+大小写
*
* @return
*/
private static String getGUID() {
StringBuilder sb = new StringBuilder();
//产生16位的强随机数
Random rd = new SecureRandom();
for (int i = 0; i < 16; i++) {
//产生0-2的3位随机数
int type = rd.nextInt(3);
switch (type) {
case 0:
//0-9的随机数
sb.append(rd.nextInt(10));
break;
case 1:
//ASCII在65-90之间为大写,获取大写随机
sb.append((char) (rd.nextInt(25) + 65));
break;
case 2:
//ASCII在97-122之间为小写,获取小写随机
sb.append((char) (rd.nextInt(25) + 97));
break;
default:
break;
}
}
return sb.toString();
}
/**
* 默认加密方法
*
* @param content 待加密内容
* @return 加密数据
*/
public String defaultEncrypt(String content) {
return encrypt(content, DEFAULT_PUBLIC_KEY, DEFAULT_IV);
}
/**
* 默认解密方法
*
* @param content 待解密内容
* @return 解密数据
*/
public static String defaultDecrypt(String content) {
return decrypt(content, DEFAULT_PUBLIC_KEY, DEFAULT_IV);
}
/**
* AES 加密操作
*
* @param content 待加密内容
* @param publicKey 加密密钥
* @param iv 使用CBC模式,需要一个向量iv,可增加加密算法的强度
* @return 加密数据
*/
public static String encrypt(String content, String publicKey, String iv) {
try {
//创建密钥器
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
//密钥key(超过16字节即128bit的key,需要替换jre中的local_policy.jar和US_export_policy.jar,否则报错:Illegal key size)
SecretKeySpec keySpec = new SecretKeySpec(publicKey.getBytes("utf-8"), KEY_ALGORITHM);
//向量iv 使用CBC模式,需要一个向量iv,增加加密算法的强度
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
//初始化为加密模式的密钥器
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
//加密
byte[] byteContent = content.getBytes("utf-8");
byte[] result = cipher.doFinal(byteContent);
//此处使用BASE64做转码功能,同时能起到2次加密的作用
return Base64.encodeBase64String(result);
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
return null;
}
/**
* AES 解密操作
*
* @param content 密文
* @param publicKey 密钥
* @param iv 使用CBC模式,需要一个向量iv,增加加密算法的强度
* @return 明文
*/
public static String decrypt(String content, String publicKey, String iv) {
try {
//创建密钥器
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
//密钥key
SecretKeySpec keySpec = new SecretKeySpec(publicKey.getBytes("utf-8"), KEY_ALGORITHM);
//向量iv
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
//初始化为解密模式的密钥器
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
byte[] encrypted = Base64.decodeBase64(content) ;
//执行操作
byte[] result = cipher.doFinal(encrypted);
return new String(result, "utf-8");
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
return null;
}
}
2. rsa
package com.cdp.dps.util;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAUtils {
private static final Logger log = LoggerFactory.getLogger(RSAUtils.class);
public static final String KEY_ALGORITHM = "RSA";
/**
* 貌似默认是RSA/NONE/PKCS1Padding,未验证
*/
public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
public static final String PUBLIC_KEY = "publicKey";
public static final String PRIVATE_KEY = "privateKey";
/**
* RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024
*/
public static final int KEY_SIZE = 512;
public static final String PLAIN_TEXT = "8613788888888";
public static final PublicKey publicKey = restorePublicKey(Base64.decodeBase64("MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIW8SMcCjTaoQBNII7ObrKKvScnvigWD5s08GQ0i3RsbqcH1TwDFP6sDy2nG8OEpgJyCygN4lVL7wuKkiCc5If0CAwEAAQ=="));
public static final PrivateKey privateKey = restorePrivateKey(Base64.decodeBase64("MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAhbxIxwKNNqhAE0gjs5usoq9Jye+KBYPmzTwZDSLdGxupwfVPAMU/qwPLacbw4SmAnILKA3iVUvvC4qSIJzkh/QIDAQABAkAOa0CFhHbpP7a43XxL7yrr125jQVpmQdRuqF4jFnE0bNxn16fK/wiQOXkapJ5KwTCB8kRAFcKfUu5Htl4aq3ABAiEA4mVUWCy4JpRkmtRWelDVQ3apcjzaF0TBliTdJDj6OgECIQCXOR8OpNmYWruLu9pdg/UNt9PBoG63QmoVv5Ef7QfP/QIhANCb1hA5hKXn7pvMNLMYcKptWM1uzPbL4CVdanfKGKgBAiEAk7O0FO6IpZmBcwMBTrOTR1nUV1umqBITYbihO8idB9UCIHDf0Q2uq5NNF6nHN8phIlQXovRN8JSceCfY4KgrMF9G"));
public static String encodeStr(String pk,String strText){
PublicKey publicKey = restorePublicKey(Base64.decodeBase64(pk));
byte[] encodedText = RSAEncode(publicKey, strText.getBytes());
return Base64.encodeBase64String(encodedText);
}
public static String encodeDefaultStr(String strText){
byte[] encodedText = RSAEncode(publicKey, strText.getBytes());
return Base64.encodeBase64String(encodedText);
}
public static String decodeDefaultStr(String encodeStr){
return RSADecode(privateKey,Base64.decodeBase64(encodeStr.getBytes()));
}
public static void main(String[] args) {
//邮件密钥
// PublicKey publicKey = restorePublicKey(Base64.decodeBase64("MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIW8SMcCjTaoQBNII7ObrKKvScnvigWD5s08GQ0i3RsbqcH1TwDFP6sDy2nG8OEpgJyCygN4lVL7wuKkiCc5If0CAwEAAQ=="));
// PrivateKey privateKey = restorePrivateKey(Base64.decodeBase64("MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAhbxIxwKNNqhAE0gjs5usoq9Jye+KBYPmzTwZDSLdGxupwfVPAMU/qwPLacbw4SmAnILKA3iVUvvC4qSIJzkh/QIDAQABAkAOa0CFhHbpP7a43XxL7yrr125jQVpmQdRuqF4jFnE0bNxn16fK/wiQOXkapJ5KwTCB8kRAFcKfUu5Htl4aq3ABAiEA4mVUWCy4JpRkmtRWelDVQ3apcjzaF0TBliTdJDj6OgECIQCXOR8OpNmYWruLu9pdg/UNt9PBoG63QmoVv5Ef7QfP/QIhANCb1hA5hKXn7pvMNLMYcKptWM1uzPbL4CVdanfKGKgBAiEAk7O0FO6IpZmBcwMBTrOTR1nUV1umqBITYbihO8idB9UCIHDf0Q2uq5NNF6nHN8phIlQXovRN8JSceCfY4KgrMF9G"));
long timeMillis = System.currentTimeMillis();
//数据库密钥
PublicKey publicKey = restorePublicKey(Base64.decodeBase64("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJds3mfVlKLfpdEG+6E+qwV+76swqas9XVe0ILD6FjshvEiRMcAXlyyKmXjd4Lth/PzDG+HMyH28V72JRaeDCpt4jEgxT8vXfLVgLsr1YJvBsmij00uVSoaA4DYU6aVLe6S1zYkcRIhnBMYNKF7temQ/Pjy0lTOT8W+aATPi/K/QIDAQAB"));
// PrivateKey privateKey = restorePrivateKey(Base64.decodeBase64("MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAzaTSCrDGR6bduTl+eO723BiOGlmjN3aBgwOn5kxcKMfhWKzmh14hBAMDI5sdgtgs7BUqOkU75C1LvOVw/w7E3wIDAQABAkAJ+nFmq2UznNktX6jPXWkFDPv4M1lEG6/1F3xSJGpkYBgvgX6OLqYsgHVegI4AUkas+J4OiWPrCR2c4VbLyKtBAiEA9usPVbBKm1ZljuYsL5SYuIIhaVG3XAYnZ0pKF7Ax4IcCIQDVNSDH7ioIzj+ZCHfnvex0y+ahGOaNZdRAD4Lm5zfG6QIhALRnm+Wkj24dWshkfcYp0MeGNHkpvklbKbD7A1V5Y4fDAiEAyUB7Dv3LA8Db23JY7JEkMCOAMbS1e+cQ8N8zaw36YnECIQCZhh2tJyuMSxMibfSXptGuNC2pcIryoy+C2U6IrYNI/w=="));
// Map<String, byte[]> keyMap = generateKeyBytes();
//
// String public_key_base64 = Base64.encodeBase64String(keyMap.get(PUBLIC_KEY));
// System.out.println(public_key_base64);
// String private_key_base64 = Base64.encodeBase64String(keyMap.get(PRIVATE_KEY));
// System.out.println(private_key_base64);
//
// // 加密
// PublicKey publicKey = restorePublicKey(keyMap.get(PUBLIC_KEY));
byte[] encodedText = RSAEncode(publicKey, PLAIN_TEXT.getBytes());
log.info("RSA encoded: {}" , Base64.encodeBase64String(encodedText));
log.info("耗时{}",System.currentTimeMillis()-timeMillis);
String s = encodeDefaultStr(PLAIN_TEXT);
System.out.println(decodeDefaultStr(s));
// // 解密
// PrivateKey privateKey = restorePrivateKey(keyMap.get(PRIVATE_KEY));
// System.out.println("RSA decoded: " + RSADecode(privateKey, encodedText));
// System.out.println("RSA 解密 decoded: " + RSADecode(privateKey, Base64.decodeBase64("CCrRwPa9pRpVebLkqj/6b2M98AkKv1vRfeduIQpF+ZtZ8vJd/PyXldx3RC9EXpk/NB4eASO2WeJFkidw26LFHA==")));
}
/**
* 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥
*
* @return
*/
public static Map<String, byte[]> generateKeyBytes() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGenerator.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, byte[]> keyMap = new HashMap<String, byte[]>();
keyMap.put(PUBLIC_KEY, publicKey.getEncoded());
keyMap.put(PRIVATE_KEY, privateKey.getEncoded());
return keyMap;
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
log.error("error {}",e);
}
return null;
}
/**
* 还原公钥,X509EncodedKeySpec 用于构建公钥的规范
*
* @param keyBytes
* @return
*/
public static PublicKey restorePublicKey(byte[] keyBytes) {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
try {
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);
return publicKey;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
// TODO Auto-generated catch block
log.error("error {}",e);
}
return null;
}
/**
* 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范
*
* @param keyBytes
* @return
*/
public static PrivateKey restorePrivateKey(byte[] keyBytes) {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
keyBytes);
try {
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);
return privateKey;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
// TODO Auto-generated catch block
log.error("error {}",e);
}
return null;
}
/**
* 加密,三步走。
*
* @param key
* @param plainText
* @return
*/
public static byte[] RSAEncode(PublicKey key, byte[] plainText) {
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(plainText);
} catch (NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | IllegalBlockSizeException
| BadPaddingException e) {
// TODO Auto-generated catch block
log.error("error {}",e);
}
return null;
}
/**
* 解密,三步走。
*
* @param key
* @param encodedText
* @return
*/
public static String RSADecode(PrivateKey key, byte[] encodedText) {
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(encodedText));
} catch (NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | IllegalBlockSizeException
| BadPaddingException e) {
// TODO Auto-generated catch block
log.error("error {}",e);
}
return null;
}
}