Java中使用RSA加解密
最近写了好多和第三方交互需要安全加密传输的需求,涉及到了AES、DES、RSA、SM2、SM3、SM4等,此处记录RSA的使用。
生成rsa秘钥对:
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为512-4096位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 得到公钥字符串
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
String str1 = "publicKeyString公钥:" + publicKeyString;
writeFile(str1);
String str2 = "privateKeyString私钥:" + privateKeyString;
writeFile(str2);
public static void writeFile(String content) {
File file = new File("C:\\Users\\Administrator\\Desktop\\1.txt");
FileOutputStream fos = null;
OutputStreamWriter osw = null;
try {
if (!file.exists()) {
boolean hasFile = file.createNewFile();
if (hasFile) {
log.info("file not exists, create new file");
}
fos = new FileOutputStream(file);
} else {
fos = new FileOutputStream(file, true);
}
osw = new OutputStreamWriter(fos, "utf-8");
// 写入内容
osw.write(content);
// 换行
osw.write("\r\n");
} catch (Exception e) {
log.info("写入文件发生异常", e);
} finally {
// 关闭流
try {
if (osw != null) {
osw.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
log.info("关闭流异常", e);
}
}
}
公钥加密私钥模式:
/**
* RSA私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
*/
public static String privateKeyDecrypt(String str, String privateKey) throws Exception {
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
// String outStr = new String(cipher.doFinal(inputByte));
//当长度过长的时候,需要分割后解密 128个字节
String outStr = new String(getMaxResultDecrypt(str, cipher));
return outStr;
}
private static byte[] getMaxResultDecrypt(String str, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
byte[] inputArray = Base64.decodeBase64(str.getBytes("UTF-8"));
int inputLength = inputArray.length;
// 最大解密字节数,超出最大字节数需要分组加密
int MAX_ENCRYPT_BLOCK = 128;
// 标识
int offSet = 0;
byte[] resultBytes = {};
byte[] cache = {};
while (inputLength - offSet > 0) {
if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
offSet += MAX_ENCRYPT_BLOCK;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}
/**
* RSA公钥加密
*
* @param str 加密字符串
* @param publicKey 公钥
* @return 密文
* @throws Exception 加密过程中的异常信息
*/
public static String publicKeyEncrypt(String str, String publicKey) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").
generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
//当长度过长的时候,需要分割后加密 117个字节
byte[] resultBytes = getMaxResultEncrypt(str, cipher);
String outStr = Base64.encodeBase64String(resultBytes);
return outStr;
}
private static byte[] getMaxResultEncrypt(String str, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException {
byte[] inputArray = str.getBytes();
int inputLength = inputArray.length;
// 最大加密字节数,超出最大字节数需要分组加密
int MAX_ENCRYPT_BLOCK = 117;
// 标识
int offSet = 0;
byte[] resultBytes = {};
byte[] cache = {};
while (inputLength - offSet > 0) {
if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
offSet += MAX_ENCRYPT_BLOCK;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}
私钥加密公钥解密:
/**
* 使用公钥解密
*/
@SneakyThrows
public static String decryptByPublicKey(String data) {
try {
return new String(getMaxResultDecrypt(data, getPublicKey(Cipher.DECRYPT_MODE)));
}catch (Exception e){
throw new Exception("解密失败|"+e.getMessage());
}
}
/**
* 使用RSA私钥解密
*
* @param str 加密字符串
*/
public static String decryptByPrivateKey(String str) {
return new String(getMaxResultDecrypt(str, getPrivateKey(Cipher.DECRYPT_MODE)));
}
/**
* 使用RSA私钥加密
* @param data 加密数据
*/
@SneakyThrows
public static String encryptByPrivateKey(String data) {
try {
return Base64.encodeBase64String(getMaxResultEncrypt(data, getPrivateKey(Cipher.ENCRYPT_MODE)));
} catch (Exception e) {
throw new Exception("加密失败|"+e.getMessage());
}
}
/**
* 当长度过长的时候,需要分割后加密 117个字节
*/
@SneakyThrows
private static byte[] getMaxResultEncrypt(String str, Cipher cipher){
try {
byte[] inputArray = str.getBytes(StandardCharsets.UTF_8.name());
int inputLength = inputArray.length;
// 最大加密字节数,超出最大字节数需要分组加密
int maxEncryptBlock = 117;
// 标识
int offSet = 0;
byte[] resultBytes = {};
byte[] cache;
while (inputLength - offSet > 0) {
if (inputLength - offSet > maxEncryptBlock) {
cache = cipher.doFinal(inputArray, offSet, maxEncryptBlock);
offSet += maxEncryptBlock;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}catch (Exception e){
e.printStackTrace();
throw new Exception("加密处理失败,"+e.getMessage());
}
}
/**
* 当长度过长的时候,需要分割后解密 128个字节
*/
@SneakyThrows
private static byte[] getMaxResultDecrypt(String str, Cipher cipher) {
try {
byte[] inputArray = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8.name()));
int inputLength = inputArray.length;
// 最大解密字节数,超出最大字节数需要分组加密
int maxEncryptBlock = 128;
int offSet = 0;
byte[] resultBytes = {};
byte[] cache;
while (inputLength - offSet > 0) {
if (inputLength - offSet > maxEncryptBlock) {
cache = cipher.doFinal(inputArray, offSet, maxEncryptBlock);
offSet += maxEncryptBlock;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}catch (Exception e){
e.printStackTrace();
throw new Exception("解密数据处理异常,"+e.getMessage());
}
}
/**
* 根据加解密类型处理公钥
*
*/
@SneakyThrows
public static Cipher getPublicKey(int mode) {
try {
String publicKey = formatString(PK);
byte[] decoded = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decoded);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(mode, key);
return cipher;
} catch (Exception e) {
throw new Exception("转换公钥异常====>>" + e.getMessage());
}
}
/**
* 根据加解密类型处理私钥
*/
@SneakyThrows
public static Cipher getPrivateKey(int mode) {
try {
//mode 加解密模式 ENCRYPT_MODE = 1 DECRYPT_MODE = 2
String privateKey = formatString(SK);
byte[] decoded = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decoded);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(mode, key);
return cipher;
} catch (Exception e) {
throw new Exception("转换私钥异常====>>" + e.getMessage());
}
}
public static String formatString(String source) {
if (source == null) {
return null;
}
return source.replace("\\r", "").replace("\\n", "").trim().replace(" ","");
}
浙公网安备 33010602011771号