maven依赖:
org.apache.axis
axis
1.4
commons-codec
commons-codec
1.10
RSAUtil工具类代码:
package common;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import javax.crypto.Cipher;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
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;
/**
* @program: Demo
* @Date: 2019/2/21 22:56
* @Author: LiJc
* @Description:
*/
public class RSAUtil {
/**
* 转密钥字符串(base64编码)
*
* @return
*/
public static String getKeyString(Key key) throws Exception {
byte[] keyBytes = key.getEncoded();
String s = new String(Base64.encodeBase64(keyBytes));
return s;
}
/**
* 得到公钥
* @param publicKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
/**
* 得到私钥
* @param privateKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* 生成密钥对
* @param pubfilePath 公钥存放的文件路径
* @param prifilePath 私钥存放的文件路径
*/
public static void genKeyPair(String pubfilePath, String prifilePath) {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = null;
try {
keyPairGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
try {
// 得到公钥字符串
String publicKeyString = getKeyString(publicKey);
// 得到私钥字符串
String privateKeyString = getKeyString(privateKey);
// 将密钥对写入到文件
FileWriter pubfw = new FileWriter(pubfilePath);
FileWriter prifw = new FileWriter(prifilePath);
BufferedWriter pubbw = new BufferedWriter(pubfw);
BufferedWriter pribw = new BufferedWriter(prifw);
pubbw.write(publicKeyString);
pribw.write(privateKeyString);
pubbw.flush();
pubbw.close();
pubfw.close();
pribw.flush();
pribw.close();
prifw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 公钥加密
* @param data 需要加密的内容
* @param publicKey 公钥
* @return
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey){
try{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return new String(Base64.encodeBase64(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), publicKey.getModulus().bitLength())));
}catch(Exception e){
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 私钥解密
* @param data 需要加密的内容
* @param privateKey 私钥
* @return
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey){
try{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), "UTF-8");
}catch(Exception e){
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
}
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
int maxBlock = 0;
if(opmode == Cipher.DECRYPT_MODE){
maxBlock = keySize / 8;
}else{
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try{
while(datas.length > offSet){
if(datas.length-offSet > maxBlock){
buff = cipher.doFinal(datas, offSet, maxBlock);
}else{
buff = cipher.doFinal(datas, offSet, datas.length-offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
}catch(Exception e){
throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e);
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
}
单元测试:
1.先生成密钥对test1()方法。
2.从密钥的txt文件中读取密钥内容进行加解密。
package common;
import org.junit.Test;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
/**
* @program: Demo
* @Date: 2019/2/21 23:07
* @Author: LiJc
* @Description:
*/
public class RSATest {
/**
* 生成密钥对
*/
@Test
public void test1(){
RSAUtil.genKeyPair("D:\\公钥.txt","D:\\私钥.txt");
}
@Test
public void test2() throws InvalidKeySpecException, NoSuchAlgorithmException {
String content = "真香警告!";
System.out.println("原始内容为:"+content);
String pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQ1IqhPNo8M/R1pHpocNuJ6enntJoB7OAaJrVoaHbvJOI4APkheX0J1UKizOGQNRr/V6vp3B+3MrPVGJ4lfRirrgnIK86PD5K/MChSWhxslWf3jQxr7AO8rMIPre7uoGjmY3pbSY82QUGDEhgDVsWTLTjWWqFQHVTwEfBPGgaktQIDAQAB";
//根据公钥key获取公钥
RSAPublicKey publicKey = RSAUtil.getPublicKey(pubkey);
//加密
String content1 = RSAUtil.publicEncrypt(content, publicKey);
System.out.println("加密后内容为:"+content1);
String prikey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJDUiqE82jwz9HWkemhw24np6ee0mgHs4BomtWhodu8k4jgA+SF5fQnVQqLM4ZA1Gv9Xq+ncH7cys9UYniV9GKuuCcgrzo8Pkr8wKFJaHGyVZ/eNDGvsA7yswg+t7u6gaOZjeltJjzZBQYMSGANWxZMtONZaoVAdVPAR8E8aBqS1AgMBAAECgYBtteOSApPa2QyM9VyYsy1LCrvafs/PN44HoVz4S3IU9B69h9cxCWOzyC3jP0p7QA9EcDhVPh90Wl8pxK0//sRpWZrKps3ZqCQKogLSHTIaRJvvgQwN26KtIwSoXDwKqpmyhufIhXdFDmSIKb8v8rF3Sl3Mt5I+hDT83fnTjyPUPQJBAOBNObrgZQ7CvMuwtKilWhAqlNbhibfc3k4dtJ+23uixUgHq+WME6w7B0NUixT6ua7v+RKZD1RO9ANDGCEIQzfsCQQClTDPsjrkerRBsXrge6xK2drisIpEFBdYoIz9lYmCHXJctkx5nhLogxxTeAJgFWBIcOgrx5OCYOQgr5p6FikkPAkA45j470sqwCOR9w3DAy1lienrRW9tkwem+5Tg5v9kiLEFCbUogPVInpzEDsFNbCEIaKXFewBxganS3gVT89WhbAkAV90NrKyg0iGEHVar4CNsKvkoaLdnBph3oZY62JVWYh1hbqRJARWYKlwoR2lhZVXPKpnfv3y9tax7H3rSwIElHAkB7j65B6+L8Ty0RiEzHCOVXnUoUTai/BZfQ5erA9yVM/VW8p1mE/qhJOTQ5hFniO0dicl3YZyaYHW1D+Z1V4naO";
//获取私钥
RSAPrivateKey privateKey = RSAUtil.getPrivateKey(prikey);
//解密
String content2 = RSAUtil.privateDecrypt(content1, privateKey);
System.out.println("解密后内容为:"+content2);
}
}