JAVA RSA加解密和加签验签
RSA非对称加密,一般采用第三方公钥加密,自己私钥加签。
例子如下:
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
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;
/**
* @author jeremy.li
* @date 2021/3/10
* @description DefaultLoanApplicationTraceSyncHandler处理类的数据加密方式
* 数据传输:发送方使用接收方公钥加密,接收方使用自己的私钥解密
* 加签:发送方私钥加签,接收方使用发送方公钥验签
*/
public class RSAUtilV2 {
/**
* 加算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 发送方--私钥
*/
private RSAPrivateKey privateKey;
/**
* 接收方--公钥
*/
private RSAPublicKey publicKey;
/**
* 只需要加密
* @param publicKeyPath
* @throws IOException
*/
public RSAUtilV2(String publicKeyPath) throws IOException {
FileInputStream publicFile = FileUtils.openInputStream(new File(publicKeyPath));
String publicFileContext = getContextByInputStream(publicFile);
loadPublicKey(publicFileContext);
}
/**
*
* @param privateKeyPath 发送方的私钥地址
* @param publicKeyPath 接收方的公钥地址
* @throws IOException
*/
public RSAUtilV2(String privateKeyPath, String publicKeyPath) throws IOException {
FileInputStream privateFile = FileUtils.openInputStream(new File(privateKeyPath));
String privateFileContext = getContextByInputStream(privateFile);
FileInputStream publicFile = FileUtils.openInputStream(new File(publicKeyPath));
String publicFileContext = getContextByInputStream(publicFile);
loadPrivateKey(privateFileContext);
loadPublicKey(publicFileContext);
}
public RSAUtilV2(String privateKey, String publicKey, Integer type) throws IOException {
loadPrivateKey(privateKey);
loadPublicKey(publicKey);
}
/**
* 从文件中读取内容
*
* @param in 输入流
*/
private String getContextByInputStream(InputStream in) {
String context = null;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String readLine = null;
StringBuilder sb = new StringBuilder();
while ((readLine = br.readLine()) != null) {
if (readLine.charAt(0) == '-') {
continue;
} else {
sb.append(readLine);
sb.append('\r');
}
}
context = sb.toString();
} catch (IOException e) {
throw new RuntimeException("密钥数据流读取错误");
} catch (NullPointerException e) {
throw new RuntimeException("密钥输入流为空");
}
return context;
}
/**
* 从字符串中加载私钥
*
* @param privateKeyStr 私钥数据字符串
* @throws Exception 加载私钥时产生的异常
*/
private void loadPrivateKey(String privateKeyStr) {
try {
byte[] buffer = Base64.decodeBase64(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("无此算法");
} catch (InvalidKeySpecException e) {
throw new RuntimeException("私钥非法");
} catch (NullPointerException e) {
throw new RuntimeException("私钥数据为空");
}
}
/**
* 从字符串中加载公钥
*
* @param publicKeyStr 公钥数据字符串
*/
private void loadPublicKey(String publicKeyStr) {
try {
byte[] buffer = Base64.decodeBase64(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("无此算法");
} catch (InvalidKeySpecException e) {
throw new RuntimeException("公钥非法");
} catch (NullPointerException e) {
throw new RuntimeException("公钥数据为空");
}
}
/**
* 加密,该方法有问题,加密数据超过117报错
* @param data
* @return
* @throws Exception
*/
public String encrypt1(String data) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = data.getBytes(CharEncoding.UTF_8);
byte decryptedData[] = cipher.doFinal(bytes);
return Base64.encodeBase64String(decryptedData);
}
/**
* 解密
* @param data
* @return
* @throws Exception
*/
public String decrypt1(String data) throws Exception {
byte[] bytes = data.getBytes(CharEncoding.UTF_8);
byte[] decodeBase64 = Base64.decodeBase64(bytes);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte encryptedData[] = cipher.doFinal(decodeBase64);
String outStr = new String(encryptedData);
return outStr;
}
/**
* 加密
* @param data
* @return
* @throws Exception
*/
public String encrypt(String data) throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = data.getBytes(CharEncoding.UTF_8);
int inputLen = bytes.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(bytes, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64.encodeBase64String(encryptedData);
}
/**
* 解密
* @param data
* @return
* @throws Exception
*/
public String decrypt(String data) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] bytes = data.getBytes(CharEncoding.UTF_8);
byte[] decodeBase64 = Base64.decodeBase64(bytes);
int inputLen = decodeBase64.length;
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(decodeBase64, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(decodeBase64, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return new String(decryptedData);
}
/**
* 加签
* @param data
* @return
* @throws Exception
*/
public String sign(String data) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey);
byte[] bytes = data.getBytes(CharEncoding.UTF_8);
signature.update(bytes);
byte[] signed = signature.sign();
return Base64.encodeBase64String(signed);
}
/**
* 验签
* @param sourceData
* @param encryptData
* @return
* @throws Exception
*/
public boolean verify(String sourceData, String encryptData) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicKey);
byte[] bytes = sourceData.getBytes(CharEncoding.UTF_8);
signature.update(bytes);
boolean verify = signature.verify(Base64.decodeBase64(encryptData));
System.out.println("验签结果:" + verify);
return verify;
}
public static void main(String[] args) {
}
}
测试类
import org.apache.commons.codec.binary.Base64;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
/**
* @author jeremy.li
* @date 2021/3/10
* @description
*/
public class RSAUtilV2Test {
private static String publicKey = null;
private static String privateKey = null;
private static RSAUtilV2 defaultRSAUtils = null;
public static void main(String[] args) throws Exception {
genKeyPair();
System.out.println("随机生成的公钥为:" + publicKey);
System.out.println("随机生成的私钥为:" + privateKey);
defaultRSAUtils = new RSAUtilV2(privateKey, publicKey, 1);
verifyRSA();
verifySign();
}
public static void verifyRSA() throws Exception {
//生成公钥和私钥
System.out.println("---------------------------验证RSA加解密-----------------------------");
String message = "{name:关羽1111111}";
String messageEn2 = defaultRSAUtils.encrypt(message);
System.out.println(message + "\t加密后的字符串为:" + messageEn2);
String messageDe2 = defaultRSAUtils.decrypt(messageEn2);
System.out.println("还原后的字符串为:" + messageDe2);
}
public static void verifySign() throws Exception {
System.out.println("---------------------------验证Sign-----------------------------");
String message = "{name:张飞}";
String messageEn = defaultRSAUtils.sign(message);
System.out.println(message + "\t生成加sign:" + messageEn);
defaultRSAUtils.verify(message, messageEn);
}
/**
* 随机生成密钥对
*
* @throws NoSuchAlgorithmException
*/
public static void genKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
publicKey = new String(Base64.encodeBase64(rsaPublicKey.getEncoded()));
// 得到私钥字符串
privateKey = new String(Base64.encodeBase64((rsaPrivateKey.getEncoded())));
}
}

浙公网安备 33010602011771号