RSA算法实现类
没有的jar包可以到maven中央仓库找
package com.jx.tmall_demo.utils;
import cn.hutool.core.codec.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* @author xiaojian
* @description
* @date 2019/3/14
**/
public class RsaUtils {
private static final String KEY_ALGORITHM = "RSA";
private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";
private static final int MAX_ENCRYPT_BLOCK = 117;
private static final int MAX_DECRYPT_BLOCK = 128;
private static final int KEY_SIZE = 1024;
public RsaUtils() {
}
/*
* *****************************************************************************
* 加密/解密
* *****************************************************************************
*/
/**
* 初始化私钥/公钥
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 公钥加密
* @param text
* @param publicKey
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String text, String publicKey) throws Exception {
byte[] data = text.getBytes();
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
for(int i = 0; inputLen - offSet > 0; offSet = i * MAX_ENCRYPT_BLOCK) {
byte[] cache;
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64.encode(encryptedData);
}
/**
* 私钥加密
* @param text
* @param privateKey
* @return
* @throws Exception
*/
public static String encryptByPrivateKey(String text, String privateKey) throws Exception {
byte[] data = text.getBytes();
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
for(int i = 0; inputLen - offSet > 0; offSet = i * MAX_ENCRYPT_BLOCK) {
byte[] cache;
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64.encode(encryptedData);
}
/**
* 公钥解密
* @param data
* @param publicKey
* @return
* @throws Exception
*/
public static String decryptByPublicKey(String data, String publicKey) throws Exception {
byte[] encryptedData = Base64.decode(data);
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
for(int i = 0; inputLen - offSet > 0; offSet = i * MAX_DECRYPT_BLOCK) {
byte[] cache;
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
byte[] decryptedData = out.toByteArray();
out.close();
return new String(decryptedData);
}
/**
* 私钥解密
* @param data
* @param privateKey
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String data, String privateKey) throws Exception {
byte[] encryptedData = Base64.decode(data);
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
for(int i = 0; inputLen - offSet > 0; offSet = i * MAX_DECRYPT_BLOCK) {
byte[] cache;
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
byte[] decryptedData = out.toByteArray();
out.close();
return new String(decryptedData);
}
/**
* 获取私钥的Base64字符串
* @param keyMap
* @return
*/
public static String getPrivateKey(Map<String, Object> keyMap){
Key key = (Key)keyMap.get(PRIVATE_KEY);
return Base64.encode(key.getEncoded());
}
/**
* 获取公钥的Base64字符串
* @param keyMap
* @return
*/
public static String getPublicKey(Map<String, Object> keyMap){
Key key = (Key)keyMap.get(PUBLIC_KEY);
return Base64.encode(key.getEncoded());
}
/**
* 生成密钥对文件
*/
public static void initPubAndPriKey(String filePath) {
try {
Map<String, Object> map = genKeyPair();
// 得到公钥字符串
String publicKeyString = getPublicKey(map);
// 得到私钥字符串
String privateKeyString = getPrivateKey(map);
// 将密钥对写入到文件
FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");
FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");
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();
}
}
/**
* 从文件中加载私钥Base64字符串
* @param path
* @return
* @throws Exception
*/
public static String loadPrivateKeyByFile(String path) throws Exception {
try {
BufferedReader br = new BufferedReader(new FileReader(path + "/privateKey.keystore"));
String readLine = null;
StringBuilder sb = new StringBuilder();
while ((readLine = br.readLine()) != null) {
sb.append(readLine);
}
br.close();
return sb.toString();
} catch (IOException e) {
throw new Exception("私钥数据读取错误");
} catch (NullPointerException e) {
throw new Exception("私钥输入流为空");
}
}
/**
* 从文件中加载公钥Base64字符串
* @param path
* @return
* @throws Exception
*/
public static String loadPublicKeyByFile(String path) throws Exception {
try {
BufferedReader br = new BufferedReader(new FileReader(path + "/publicKey.keystore"));
String readLine = null;
StringBuilder sb = new StringBuilder();
while ((readLine = br.readLine()) != null) {
sb.append(readLine);
}
br.close();
return sb.toString();
} catch (IOException e) {
throw new Exception("公钥数据流读取错误");
} catch (NullPointerException e) {
throw new Exception("公钥输入流为空");
}
}
/*
* *****************************************************************************
* 签名/校验
* *****************************************************************************
*/
/**
* RSA签名
* @param content 待签名数据
* @param privateKey 商户私钥
* @param encode 字符集编码
* @return 签名值
*/
public static String sign(String content, String privateKey, String encode) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey) );
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update( content.getBytes(encode));
byte[] signed = signature.sign();
return Base64.encode(signed);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String sign(String content, String privateKey) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update( content.getBytes());
byte[] signed = signature.sign();
return Base64.encode(signed);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA验签名检查
* @param content 待签名数据
* @param sign 签名值
* @param publicKey 分配给开发商公钥
* @param encode 字符集编码
* @return 布尔值
*/
public static boolean doCheck(String content, String sign, String publicKey,String encode) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature
.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update( content.getBytes(encode) );
boolean bverify = signature.verify( Base64.decode(sign) );
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean doCheck(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update( content.getBytes() );
boolean bverify = signature.verify( Base64.decode(sign) );
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
测试类
package com.jx.tmall_demo;
import com.jx.tmall_demo.utils.RsaUtils;
/**
* @author xiaojian
* @description
* @date 2019/3/14
**/
public class Test {
public static void main(String[] args)throws Exception {
String filepath="E:/rsa/";
RsaUtils.initPubAndPriKey(filepath);
System.out.println("--------------公钥加密私钥解密过程--------------");
String origData="公钥加密私钥解密";
System.out.println("原文:"+origData);
//公钥加密过程
String cipherData= RsaUtils.encryptByPublicKey(origData, RsaUtils.loadPublicKeyByFile(filepath));
System.out.println("加密:"+cipherData);
//私钥解密过程
String afterData= RsaUtils.decryptByPrivateKey(cipherData, RsaUtils.loadPrivateKeyByFile(filepath));
System.out.println("解密:"+afterData);
System.out.println("--------------私钥加密公钥解密过程--------------");
origData="私钥加密公钥解密";
System.out.println("原文:"+origData);
//私钥加密过程
cipherData= RsaUtils.encryptByPrivateKey(origData, RsaUtils.loadPrivateKeyByFile(filepath));
System.out.println("加密:"+cipherData);
//公钥解密过程
afterData= RsaUtils.decryptByPublicKey(cipherData, RsaUtils.loadPublicKeyByFile(filepath));
System.out.println("解密:"+afterData);
System.out.println("--------------私钥签名过程--------------");
String content="用于签名的原始数据";
String sign= RsaUtils.sign(content, RsaUtils.loadPrivateKeyByFile(filepath));
System.out.println("签名原串:"+content);
System.out.println("签名串:"+sign);
System.out.println("--------------公钥校验签名--------------");
System.out.println("签名原串:"+content);
System.out.println("签名串:"+sign);
System.out.println("验签结果:"+ RsaUtils.doCheck(content, sign, RsaUtils.loadPublicKeyByFile(filepath)));
}
}