參考:https://www.cnblogs.com/yaowen/p/9226566.html
RSAEncrypt:
package com.zhx.base.interceptor;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
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;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
public class RSAEncrypt {
/**
* 字節數據轉字符串專用集合
*/
private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 隨機生成密鑰對
*/
public static void genKeyPair(String filePath) {
// 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 {
// 得到公鑰字符串
Base64 base64 = new Base64();
String publicKeyString = new String(base64.encode(publicKey.getEncoded()));
// 得到私鑰字符串
String privateKeyString = new String(base64.encode(privateKey.getEncoded()));
// 將密鑰對寫入到文件
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();
}
}
/**
* 從文件中輸入流中加載公鑰
*
* @param in
* 公鑰輸入流
* @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("公鑰輸入流爲空");
}
}
/**
* 從字符串中加載公鑰
*
* @param publicKeyStr
* 公鑰數據字符串
* @throws Exception
* 加載公鑰時產生的異常
*/
public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
throws Exception {
try {
Base64 base64 = new Base64();
byte[] buffer = base64.decode(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此算法");
} catch (InvalidKeySpecException e) {
throw new Exception("公鑰非法");
} catch (NullPointerException e) {
throw new Exception("公鑰數據爲空");
}
}
/**
* 從文件中加載私鑰
*
* @param keyFileName
* 私鑰文件名
* @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("私鑰輸入流爲空");
}
}
public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
throws Exception {
try {
Base64 base64 = new Base64();
byte[] buffer = base64.decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此算法");
} catch (InvalidKeySpecException e) {
throw new Exception("私鑰非法");
} catch (NullPointerException e) {
throw new Exception("私鑰數據爲空");
}
}
/**
* 公鑰加密過程
*
* @param publicKey
* 公鑰
* @param plainTextData
* 明文數據
* @return
* @throws Exception
* 加密過程中的異常信息
*/
public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
throws Exception {
if (publicKey == null) {
throw new Exception("加密公鑰爲空, 請設置");
}
Cipher cipher = null;
try {
// 使用默認RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(plainTextData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此加密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
} catch (InvalidKeyException e) {
throw new Exception("加密公鑰非法,請檢查");
} catch (IllegalBlockSizeException e) {
throw new Exception("明文長度非法");
} catch (BadPaddingException e) {
throw new Exception("明文數據已損壞");
}
}
/**
* 私鑰加密過程
*
* @param privateKey
* 私鑰
* @param plainTextData
* 明文數據
* @return
* @throws Exception
* 加密過程中的異常信息
*/
public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)
throws Exception {
if (privateKey == null) {
throw new Exception("加密私鑰爲空, 請設置");
}
Cipher cipher = null;
try {
// 使用默認RSA
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] output = cipher.doFinal(plainTextData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此加密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
} catch (InvalidKeyException e) {
throw new Exception("加密私鑰非法,請檢查");
} catch (IllegalBlockSizeException e) {
throw new Exception("明文長度非法");
} catch (BadPaddingException e) {
throw new Exception("明文數據已損壞");
}
}
/**
* 私鑰解密過程
*
* @param privateKey
* 私鑰
* @param cipherData
* 密文數據
* @return 明文
* @throws Exception
* 解密過程中的異常信息
*/
public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
throws Exception {
if (privateKey == null) {
throw new Exception("解密私鑰爲空, 請設置");
}
Cipher cipher = null;
try {
// 使用默認RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] output = cipher.doFinal(cipherData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此解密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
} catch (InvalidKeyException e) {
throw new Exception("解密私鑰非法,請檢查");
} catch (IllegalBlockSizeException e) {
throw new Exception("密文長度非法");
} catch (BadPaddingException e) {
throw new Exception("密文數據已損壞");
}
}
/**
* 公鑰解密過程
*
* @param publicKey
* 公鑰
* @param cipherData
* 密文數據
* @return 明文
* @throws Exception
* 解密過程中的異常信息
*/
public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)
throws Exception {
if (publicKey == null) {
throw new Exception("解密公鑰爲空, 請設置");
}
Cipher cipher = null;
try {
// 使用默認RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(cipherData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此解密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
} catch (InvalidKeyException e) {
throw new Exception("解密公鑰非法,請檢查");
} catch (IllegalBlockSizeException e) {
throw new Exception("密文長度非法");
} catch (BadPaddingException e) {
throw new Exception("密文數據已損壞");
}
}
/**
* 字節數據轉十六進制字符串
*
* @param data
* 輸入數據
* @return 十六進制內容
*/
public static String byteArrayToString(byte[] data) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < data.length; i++) {
// 取出字節的高四位 作爲索引得到相應的十六進制標識符 注意無符號右移
stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
// 取出字節的低四位 作爲索引得到相應的十六進制標識符
stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
if (i < data.length - 1) {
stringBuilder.append(' ');
}
}
return stringBuilder.toString();
}
}
RSASignature:
package com.zhx.base.interceptor;
import org.apache.commons.codec.binary.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA簽名驗籤類
*/
public class RSASignature {
/**
* 簽名算法
*/
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
/**
* RSA簽名
*
* @param content 待簽名數據
* @param privateKey 商戶私鑰
* @param encode 字符集編碼
* @return 簽名值
*/
public static String sign(String content, String privateKey, String encode) {
try {
Base64 base64 = new Base64();
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(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes(encode));
byte[] signed = signature.sign();
return new String(base64.encode(signed));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String sign(String content, String privateKey) {
try {
Base64 base64 = new Base64();
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(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes());
byte[] signed = signature.sign();
return new String(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");
Base64 base64 = new Base64();
byte[] encodedKey = base64.decode(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
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");
Base64 base64 = new Base64();
byte[] encodedKey = base64.decode(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes());
boolean bverify = signature.verify(base64.decode(sign));
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
MainTest:
package com.zhx.base.interceptor;
import org.apache.commons.codec.binary.Base64;
public class MainTest {
public static void main(String[] args) throws Exception {
String filepath = "C:\\Users\\admin\\Desktop\\test";
RSAEncrypt.genKeyPair(filepath);
Base64 base64 = new Base64();
System.out.println("--------------公鑰加密私鑰解密過程-------------------");
String plainText = "ihep_公鑰加密私鑰解密";
// 公鑰加密過程
byte[] cipherData = RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)),
plainText.getBytes());
String cipher = new String(base64.encode(cipherData));
// 私鑰解密過程
byte[] res = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)),
base64.decode(cipher));
String restr = new String(res);
System.out.println("原文:" + plainText);
System.out.println("加密:" + cipher);
System.out.println("解密:" + restr);
System.out.println();
System.out.println("--------------私鑰加密公鑰解密過程-------------------");
plainText = "ihep_私鑰加密公鑰解密";
// 私鑰加密過程
cipherData = RSAEncrypt.encrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)),
plainText.getBytes());
cipher = new String(base64.encode(cipherData));
// 公鑰解密過程
res = RSAEncrypt.decrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)),
base64.decode(cipher));
restr = new String(res);
System.out.println("原文:" + plainText);
System.out.println("加密:" + cipher);
System.out.println("解密:" + restr);
System.out.println();
System.out.println("---------------私鑰簽名過程------------------");
String content = "ihep_這是用於簽名的原始數據";
String signstr = RSASignature.sign(content, RSAEncrypt.loadPrivateKeyByFile(filepath));
System.out.println("簽名原串:" + content);
System.out.println("簽名串:" + signstr);
System.out.println();
System.out.println("---------------公鑰校驗簽名------------------");
System.out.println("簽名原串:" + content);
System.out.println("簽名串:" + signstr);
System.out.println("驗簽結果:" + RSASignature.doCheck(content, signstr, RSAEncrypt.loadPublicKeyByFile(filepath)));
System.out.println();
}
}