/**
* RSA 非对称加密算法工具类
*
* @ClassName: RSAUtil
* @Version: 1.0
*/
public class RSAUtil {
/**
* 加密算法
*/
private static final String KEY_ALGORITHM = "RSA";
/**
* RSA位数,采用2048,则加密密文和解密密文需要使用245和256
*/
private static final Integer INITIALIZE_LENGTH = 2048;
/**
* 公钥
*/
public static String publicKey = "";
/**
* 私钥
*/
public static String privateKey = "";
/**
* 生成公钥和私钥
*/
public static void generateKey() {
// 1.初始化秘钥
KeyPairGenerator keyPairGenerator;
try {
keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
// 随机数生成器
SecureRandom sr = new SecureRandom();
// 设置秘钥长度
keyPairGenerator.initialize(INITIALIZE_LENGTH, sr);
// 开始创建
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
// 进行转码
publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
// 进行转码
privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 私钥匙加密或解密
*
* @param: content 需要解密的字符串
* @param: privateKeyStr 私钥
* @param: opmode Cipher.DECRYPT_MODE=2 解密
* @return: 解密后的字符串
*/
public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {
// 私钥要用PKCS8进行处理
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
KeyFactory keyFactory;
PrivateKey privateKey;
Cipher cipher;
byte[] result;
String text = null;
try {
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 还原Key对象
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(opmode, privateKey);
//加密解密
text = encryptTxt(opmode, cipher, content);
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
public static String encryptTxt(int opmode, Cipher cipher, String content) {
byte[] result;
String text = null;
try {
// 加密
if (opmode == Cipher.ENCRYPT_MODE) {
result = cipher.doFinal(content.getBytes());
text = Base64.encodeBase64String(result);
} else if (opmode == Cipher.DECRYPT_MODE) {
// 解密
result = cipher.doFinal(Base64.decodeBase64(content));
text = new String(result, StandardCharsets.UTF_8);
}
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
/**
* 公钥匙加密或解密
*
* @param: content 需要加密的字符串
* @param: publicKeyStr 公钥字符串
* @param: opmode Cipher.ENCRYPT_MODE=1 加密
* @return: 密文
*/
public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {
// 公钥要用X509进行处理
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
KeyFactory keyFactory;
PublicKey publicKey;
Cipher cipher;
byte[] result;
String text = null;
try {
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 还原Key对象
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(opmode, publicKey);
text = encryptTxt(opmode, cipher, content);
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
/**
* 读取文件中的公钥
*
* @return: java.security.PublicKey
**/
public static PublicKey getPublicKey(String pathPublicKeyName) {
String publicKeyStr = FileUtils.getKey(pathPublicKeyName);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
PublicKey publicKey = null;
try {
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
publicKey = factory.generatePublic(x509EncodedKeySpec);
} catch (Exception e) {
e.getMessage();
}
return publicKey;
}
/**
* 读取文件中的私钥
*
* @param pathPrivateKeyName:
* @return: java.security.PrivateKey
**/
public static PrivateKey getPrivateKey(String pathPrivateKeyName) {
String privateKeyStr = FileUtils.getKey(pathPrivateKeyName);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
PrivateKey privateKey = null;
try {
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);
} catch (Exception e) {
e.getMessage();
}
return privateKey;
}
//测试
public static void main(String[] args) throws Exception {
//文件地址 和 文件名
String path = "D:/demo/";
String publicFileName = "publicKey.txt";
String privateFileName = "privateKey.txt";
// 1. 生成(公钥和私钥)密钥对
RSAUtil.generateKey();
System.out.println("公钥:" + RSAUtil.publicKey);
System.out.println("私钥:" + RSAUtil.privateKey);
System.out.println("----------公钥加密私钥解密(推荐),非对称加密,公钥保存在客户端,私钥保存在服务端-------------");
//2、将公钥 私钥 输入到文件中
FileUtils.saveFile(path + publicFileName, RSAUtil.publicKey.getBytes());
FileUtils.saveFile(path + privateFileName, RSAUtil.privateKey.getBytes());
//3、从文件中获取公钥私钥
String publicKey1 = FileUtils.getKey(path + publicFileName);
String privateKey1 = FileUtils.getKey(path + privateFileName);
System.out.println("获取到文件中的公钥:" + publicKey1);
System.out.println("获取到文件中的私钥:" + privateKey1);
//4、原始密码
String textsr = "admin";
System.out.println("原始密码:" + textsr);
//5、使用生成的公钥加密
String encryptByPublic = RSAUtil.encryptByPublicKey(textsr, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);
System.out.println("公钥加密的密码:" + encryptByPublic);
//6、使用文件中读取的公钥加密,
String encryptByPublic1 = RSAUtil.encryptByPublicKey(textsr, publicKey1, Cipher.ENCRYPT_MODE);
System.out.println("文件中的公钥加密的密码:" + encryptByPublic1);
//7、使用生成的私钥解密
String jiemi = RSAUtil.encryptByprivateKey(encryptByPublic, RSAUtil.privateKey, Cipher.DECRYPT_MODE);
System.out.println("私钥解密:" + jiemi);
//8、使用文件中读取的私钥解密
String encryptByPrivate1 = RSAUtil.encryptByprivateKey(encryptByPublic, privateKey1, Cipher.DECRYPT_MODE);
System.out.println("文件中的私钥解密:" + encryptByPrivate1);
}
FileUtils
/**
* @Description: 资源文件上传工具类
* @ClassName: FileUtils
*/
@Log4j2
public class FileUtils {
/**
* @param file 文件
* @param path 文件存放路径
* @return
*/
public static String upload(MultipartFile file, String path) {
//获取文件名后缀
String fileLastType = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf("."));
//生成文件名称
String newFileName = UUID.randomUUID().toString().replaceAll("-", "");
// 生成新的文件名
String realPath = path + "/" + newFileName + fileLastType;
//使用原文件名
//String realPath = path + "/" + file.getOriginalFilename();
File dest = new File(realPath);
//判断文件父目录是否存在
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdir();
}
try {
//保存文件
file.transferTo(dest);
return newFileName + fileLastType;
} catch (IllegalStateException e) {
log.error(e);
return "error";
} catch (IOException e) {
log.error(e);
return "error";
}
}
/**
* 添加文件
*
* @param filename: 文件地址 + 文件名称
* @param data: 数据
* @return: void
**/
public static void saveFile(String filename, byte[] data) throws Exception {
if (data != null) {
File file = new File(filename);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir();
}
if (file.exists()) {
file.delete();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(data, 0, data.length);
fos.flush();
fos.close();
}
}
/**
* 读取文件内容
*
* @param filename: 文件地址 + 文件名称
* @return: java.lang.String
**/
public static String getKey(String filename) {
StringBuffer sbf = new StringBuffer();
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
String str;
while ((str = in.readLine()) != null) {
sbf.append(str);
}
} catch (IOException e) {
}
return sbf.toString();
}
}