本博客的代码经过自己慢慢调试,全部都成功运行
特别注意的是:
- Base64的包要这个,import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
- key的长度是根据密钥的长度决定,private static final int KEY_SIZE = 1024;
- 在线生成密钥对的网址:http://web.chacuo.net/netrsakeypair,可以自己生成密钥对来验证
- php格式密钥转换为Java格式的密钥:public static String getCerToPublicKey() throws CertificateException
直接贴代码
package wofang.common.utils;
import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
/**
* @author 林高禄
* @create 2020-05-15-15:09
*/
public class RsaUtils {
/** *//**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 填充方式
*/
public static final String CIPHERALGORITHM = "RSA/ECB/PKCS1Padding";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* php公钥的key
*/
public static final String PHP_PUBLIC_KEY = "-----BEGIN CERTIFICATE-----\n" +
"MIICjTCCAfYCCQD0L/1fW/xYMjANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMC\n" +
"Q04xDzANBgNVBAgMBkhhaU5hbjEPMA0GA1UEBwwGSGFpS291MQ8wDQYDVQQKDAZX\n" +
"b0ZhbmcxDzANBgNVBAsMBldvRmFuZzEZMBcGA1UEAwwQd3hhcGkud29mYW5nLmNv\n" +
"bTEcMBoGCSqGSIb3DQEJARYNd29mYW5nQHFxLmNvbTAeFw0xODA1MjIwNjQ2NTJa\n" +
"Fw0yODA1MTkwNjQ2NTJaMIGKMQswCQYDVQQGEwJDTjEPMA0GA1UECAwGSGFpTmFu\n" +
"MQ8wDQYDVQQHDAZIYWlLb3UxDzANBgNVBAoMBldvRmFuZzEPMA0GA1UECwwGV29G\n" +
"YW5nMRkwFwYDVQQDDBB3eGFwaS53b2ZhbmcuY29tMRwwGgYJKoZIhvcNAQkBFg13\n" +
"b2ZhbmdAcXEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo5zysftrH\n" +
"mlfuZ3Fokzha1w+rmZc3MIgWL+3Z7URCasSr3TtSaaTYnl91VCfTF78rEhdZG7h6\n" +
"8kgzovc5alMRmPBtEe9Enr9G+XPN6RCu6Y1nFRepIIscXghBpISj1Cofe6SUGgHY\n" +
"5S9THNZsXSHxsvNLcPcOFEZtBKcSz9FXlwIDAQABMA0GCSqGSIb3DQEBCwUAA4GB\n" +
"AHEIGEVJSQmLH3qPu4/8qHVYF3iB3sFDrnU+aYm0L0b/y0TeTjtztpAerMTK3LLA\n" +
"RBVxjwSQzdIf9EDihYl/VrZSlxjkvoE2k1dRxNg1dBZLraZPle6cgEq+l2nh6FD9\n" +
"Xzx8udLo2sr5wbGsldmyTZGcpjGSOOecGaGh6Xvh0CEC\n" +
"-----END CERTIFICATE-----";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* 长度
*/
private static final int KEY_SIZE = 1024;
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = KEY_SIZE / 8 - 11;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;
/**
* 用于封装随机产生的公钥与私钥
*/
private static Map<String, Key> keyMap = new HashMap<String, Key>();
/**
* 生成密钥对(公钥和私钥)
* @throws Exception 异常
*/
public static void genKeyPair() throws Exception {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
// 初始化密钥对生成器
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 得到公钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
}
/**
* 密钥转换,去除其他格式,换行符等
* @param privateKey 私钥
* @return String
*/
public static String keyTransformation(String privateKey,String begin,String end){
return privateKey.replace(begin, "")
.replace(end, "")
.replace("\r\n", "")
.replace("\r", "")
.replace("\n", "") ;
}
/**
* 获取私钥
* @return String
*/
public static String getPrivateKey(){
Key key = keyMap.get(PRIVATE_KEY);
return Base64.encode(key.getEncoded());
}
/**
* 获取公钥
* @return String
*/
public static String getPublicKey(){
Key key = keyMap.get(PUBLIC_KEY);
return Base64.encode(key.getEncoded());
}
/**
* php格式密钥转换为Java格式的密钥
* BEGIN CERTIFICATE格式解析密钥
* @Return: java.security.PublicKey
*/
public static String getCerToPublicKey() throws CertificateException {
//FileInputStream file = new FileInputStream("D://publicKey.cer");
String phpPublicKey = keyTransformation(RsaUtils.PHP_PUBLIC_KEY,"-----BEGIN CERTIFICATE-----","-----END CERTIFICATE-----");
byte[] phpKeyBytes = Base64.decode(phpPublicKey);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(phpKeyBytes);
X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
PublicKey publicKey = certificate.getPublicKey();
/* CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(file);
PublicKey publicKey = certificate.getPublicKey();*/
String strKey = "-----BEGIN PUBLIC KEY-----\n"
+ Base64.encode(publicKey.getEncoded())
+ "\n-----END PUBLIC KEY-----";
return strKey;
}
/**
* 用私钥对信息生成数字签名
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return String
* @throws Exception 异常
*/
public static String sign(byte[] data, String privateKey) throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64.encode(signature.sign());
}
/**
* 校验数字签名
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return boolean
* @throws Exception 异常
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64.decode(sign));
}
/**
* 分片私钥解密
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey, String cipherAlgorithm)
throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance(keyFactory.getAlgorithm());
}
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 分片公钥解密
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey,String cipherAlgorithm)
throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance(keyFactory.getAlgorithm());
}
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 分片公钥加密
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey,String cipherAlgorithm)
throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance(keyFactory.getAlgorithm());
}
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream(MAX_ENCRYPT_BLOCK);
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
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++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* 分片私钥加密
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey,String cipherAlgorithm)
throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance(keyFactory.getAlgorithm());
}
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.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(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* RSA全部公钥加密
* @param str 加密字符串
* @param publicKey 公钥
* @param cipherAlgorithm 填充方式
* @return 密文
* @throws Exception 加密过程中的异常信息
*/
public static String encrypt(String str, String publicKey,String cipherAlgorithm) throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes));
//RSA加密
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance("RSA");
}
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return Base64.encode(cipher.doFinal(str.getBytes("UTF-8")));
}
/**
* RSA全部私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @param cipherAlgorithm 填充方式
* @return 明文
* @throws Exception 解密过程中的异常信息
*/
public static String decrypt(String str, String privateKey,String cipherAlgorithm) throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
//64位解码加密后的字符串
byte[] inputByte = Base64.decode(str);
byte[] keyBytes = Base64.decode(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
//RSA解密
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance("RSA");
}
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
public static void main(String[] args) {
Map<String,Object> parameters = new LinkedHashMap<>();
parameters.put("t","10086");
parameters.put("b",10533L);
// 随机字符串
String randomString = RandomStringUtils.randomAlphanumeric(10);
parameters.put("nonceStr",randomString);
String sign = MD5Utils.createSign("UTF-8", parameters, "&key=", null, true);
System.out.println("sign=:"+sign);
parameters.put("sign",sign);
// map转为Json字符串
String mapString = JSON.toJSONString(parameters);
if(StringUtils.isBlank(mapString)){
return;
}
try {
RsaUtils.genKeyPair();
System.out.println(mapString);
String messageEn = encrypt(mapString, RsaUtils.getPublicKey(),null);
System.out.println("我的key全部加密密文1:"+messageEn);
String decrypt = RsaUtils.decrypt(messageEn, RsaUtils.getPrivateKey(),null);
System.out.println("我的key全部解密原文1:"+decrypt);
byte[] bytes = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), RsaUtils.getPublicKey(),null);;
String ws = Base64.encode(bytes);
System.out.println("我的key分片加密密文1:"+ws);
byte[] decode = Base64.decode(ws);
byte[] bytes1 = RsaUtils.decryptByPrivateKey(decode, RsaUtils.getPrivateKey(),null);
System.out.println("我的key分片解密原文1:"+new String(bytes1));
String cerToPublicKey = getCerToPublicKey();
System.out.println("转换后的key:"+ cerToPublicKey);
byte[] bytes2 = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), cerToPublicKey,RsaUtils.CIPHERALGORITHM);
String s2 = Base64.encode(bytes2);
System.out.println("他的key分片加密密文1:"+s2);
s2 = s2.replace("+", "\\\\u002b");
System.out.println("他的key分片加密密文1:"+s2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
或者是这份代码,这份把分片加解密共用的封装起来了
package wofang.common.utils;
import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
/**
* @author 林高禄
* @create 2020-05-15-15:09
*/
public class RsaUtils {
/** *//**
* 加密算法RSA
*/
private static final String KEY_ALGORITHM = "RSA";
/**
* 填充方式
*/
public static final String CIPHERALGORITHM = "RSA/ECB/PKCS1Padding";
/**
* 签名算法
*/
private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* php公钥的key
*/
private static final String PHP_PUBLIC_KEY = "-----BEGIN CERTIFICATE-----\n" +
"MIICjTCCAfYCCQD0L/1fW/xYMjANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMC\n" +
"Q04xDzANBgNVBAgMBkhhaU5hbjEPMA0GA1UEBwwGSGFpS291MQ8wDQYDVQQKDAZX\n" +
"b0ZhbmcxDzANBgNVBAsMBldvRmFuZzEZMBcGA1UEAwwQd3hhcGkud29mYW5nLmNv\n" +
"bTEcMBoGCSqGSIb3DQEJARYNd29mYW5nQHFxLmNvbTAeFw0xODA1MjIwNjQ2NTJa\n" +
"Fw0yODA1MTkwNjQ2NTJaMIGKMQswCQYDVQQGEwJDTjEPMA0GA1UECAwGSGFpTmFu\n" +
"MQ8wDQYDVQQHDAZIYWlLb3UxDzANBgNVBAoMBldvRmFuZzEPMA0GA1UECwwGV29G\n" +
"YW5nMRkwFwYDVQQDDBB3eGFwaS53b2ZhbmcuY29tMRwwGgYJKoZIhvcNAQkBFg13\n" +
"b2ZhbmdAcXEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo5zysftrH\n" +
"mlfuZ3Fokzha1w+rmZc3MIgWL+3Z7URCasSr3TtSaaTYnl91VCfTF78rEhdZG7h6\n" +
"8kgzovc5alMRmPBtEe9Enr9G+XPN6RCu6Y1nFRepIIscXghBpISj1Cofe6SUGgHY\n" +
"5S9THNZsXSHxsvNLcPcOFEZtBKcSz9FXlwIDAQABMA0GCSqGSIb3DQEBCwUAA4GB\n" +
"AHEIGEVJSQmLH3qPu4/8qHVYF3iB3sFDrnU+aYm0L0b/y0TeTjtztpAerMTK3LLA\n" +
"RBVxjwSQzdIf9EDihYl/VrZSlxjkvoE2k1dRxNg1dBZLraZPle6cgEq+l2nh6FD9\n" +
"Xzx8udLo2sr5wbGsldmyTZGcpjGSOOecGaGh6Xvh0CEC\n" +
"-----END CERTIFICATE-----";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* 长度
*/
private static final int KEY_SIZE = 1024;
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = KEY_SIZE / 8 - 11;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;
/**
* 用于封装随机产生的公钥与私钥
*/
private static Map<String, Key> keyMap = new HashMap<String, Key>();
/**
* 生成密钥对(公钥和私钥)
* @throws Exception 异常
*/
public static void genKeyPair() throws Exception {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
// 初始化密钥对生成器
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 得到公钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
}
/**
* 密钥转换,去除其他格式,换行符等
* @param privateKey 私钥
* @return String
*/
public static String keyTransformation(String privateKey,String begin,String end){
return privateKey.replace(begin, "")
.replace(end, "")
.replace("\r\n", "")
.replace("\r", "")
.replace("\n", "") ;
}
/**
* 获取私钥
* @return String
*/
public static String getPrivateKey(){
Key key = keyMap.get(PRIVATE_KEY);
return Base64.encode(key.getEncoded());
}
/**
* 获取公钥
* @return String
*/
public static String getPublicKey(){
Key key = keyMap.get(PUBLIC_KEY);
return Base64.encode(key.getEncoded());
}
/**
* php格式密钥转换为Java格式的密钥
* BEGIN CERTIFICATE格式解析密钥
* @Return: java.security.PublicKey
*/
public static String getCerToPublicKey() throws CertificateException {
//FileInputStream file = new FileInputStream("D://publicKey.cer");
String phpPublicKey = keyTransformation(RsaUtils.PHP_PUBLIC_KEY,"-----BEGIN CERTIFICATE-----","-----END CERTIFICATE-----");
byte[] phpKeyBytes = Base64.decode(phpPublicKey);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(phpKeyBytes);
X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
PublicKey publicKey = certificate.getPublicKey();
/* CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(file);
PublicKey publicKey = certificate.getPublicKey();*/
String strKey = "-----BEGIN PUBLIC KEY-----\n"
+ Base64.encode(publicKey.getEncoded())
+ "\n-----END PUBLIC KEY-----";
return strKey;
}
/**
* 用私钥对信息生成数字签名
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return String
* @throws Exception 异常
*/
public static String sign(byte[] data, String privateKey) throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64.encode(signature.sign());
}
/**
* 校验数字签名
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return boolean
* @throws Exception 异常
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64.decode(sign));
}
/**
* 分片私钥解密
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey, String cipherAlgorithm)
throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);
return encryptAndDecrypt(encryptedData,keyFactory,priKey,Cipher.DECRYPT_MODE,MAX_DECRYPT_BLOCK,cipherAlgorithm);
}
/**
* 分片公钥解密
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey,String cipherAlgorithm)
throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key pubKey = keyFactory.generatePublic(x509KeySpec);
return encryptAndDecrypt(encryptedData,keyFactory,pubKey,Cipher.DECRYPT_MODE,MAX_DECRYPT_BLOCK,cipherAlgorithm);
}
/**
* 分片公钥加密
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey,String cipherAlgorithm)
throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key pubKey = keyFactory.generatePublic(x509KeySpec);
return encryptAndDecrypt(data,keyFactory,pubKey,Cipher.ENCRYPT_MODE,MAX_ENCRYPT_BLOCK,cipherAlgorithm);
}
/**
* 分片私钥加密
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey,String cipherAlgorithm)
throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);
return encryptAndDecrypt(data,keyFactory,priKey,Cipher.ENCRYPT_MODE,MAX_ENCRYPT_BLOCK,cipherAlgorithm);
}
/**
*
* @param data 加密或解密数据
* @param keyFactory keyFactory
* @param key 私钥或者公钥
* @param cipherMode 模式,Cipher.ENCRYPT_MODE-加密,Cipher.DECRYPT_MODE-解密
* @param maxBlock 最大加解密明文大小
* @param cipherAlgorithm 填充方式
* @return byte[]
* @throws Exception 异常
*/
private static byte[] encryptAndDecrypt(byte[] data, KeyFactory keyFactory,Key key,int cipherMode,int maxBlock,String cipherAlgorithm) throws Exception{
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance(keyFactory.getAlgorithm());
}
cipher.init(cipherMode, key);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > maxBlock) {
cache = cipher.doFinal(data, offSet, maxBlock);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * maxBlock;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* RSA全部公钥加密
* @param str 加密字符串
* @param publicKey 公钥
* @param cipherAlgorithm 填充方式
* @return 密文
* @throws Exception 加密过程中的异常信息
*/
public static String encrypt(String str, String publicKey,String cipherAlgorithm) throws Exception {
publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
byte[] keyBytes = Base64.decode(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes));
//RSA加密
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance("RSA");
}
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return Base64.encode(cipher.doFinal(str.getBytes("UTF-8")));
}
/**
* RSA全部私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @param cipherAlgorithm 填充方式
* @return 明文
* @throws Exception 解密过程中的异常信息
*/
public static String decrypt(String str, String privateKey,String cipherAlgorithm) throws Exception {
privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
//64位解码加密后的字符串
byte[] inputByte = Base64.decode(str);
byte[] keyBytes = Base64.decode(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
//RSA解密
Cipher cipher;
if(StringUtil.isNotBlank(cipherAlgorithm)){
cipher = Cipher.getInstance(cipherAlgorithm);
}else{
cipher = Cipher.getInstance("RSA");
}
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
public static void main(String[] args) {
Map<String,Object> parameters = new LinkedHashMap<>();
parameters.put("t","10086");
parameters.put("b",10533L);
// 随机字符串
String randomString = RandomStringUtils.randomAlphanumeric(10);
parameters.put("nonceStr",randomString);
String sign = MD5Utils.createSign("UTF-8", parameters, "&key=", null, true);
System.out.println("sign=:"+sign);
parameters.put("sign",sign);
// map转为Json字符串
String mapString = JSON.toJSONString(parameters);
if(StringUtils.isBlank(mapString)){
return;
}
try {
RsaUtils.genKeyPair();
System.out.println(mapString);
String messageEn = encrypt(mapString, RsaUtils.getPublicKey(),null);
System.out.println("我的key全部加密密文1:"+messageEn);
String decrypt = RsaUtils.decrypt(messageEn, RsaUtils.getPrivateKey(),null);
System.out.println("我的key全部解密原文1:"+decrypt);
byte[] bytes = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), RsaUtils.getPublicKey(),null);;
String ws = Base64.encode(bytes);
System.out.println("我的key分片加密密文1:"+ws);
byte[] decode = Base64.decode(ws);
byte[] bytes1 = RsaUtils.decryptByPrivateKey(decode, RsaUtils.getPrivateKey(),null);
System.out.println("我的key分片解密原文1:"+new String(bytes1));
String cerToPublicKey = getCerToPublicKey();
System.out.println("转换后的key:"+ cerToPublicKey);
byte[] bytes2 = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), cerToPublicKey,RsaUtils.CIPHERALGORITHM);
String s2 = Base64.encode(bytes2);
System.out.println("他的key分片加密密文1:"+s2);
s2 = s2.replace("+", "\\\\u002b");
System.out.println("他的key分片加密密文1:"+s2);
} catch (Exception e) {
e.printStackTrace();
}
}
}