importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;importjava.security.InvalidKeyException;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.security.spec.InvalidKeySpecException;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjavax.crypto.BadPaddingException;importjavax.crypto.Cipher;importjavax.crypto.IllegalBlockSizeException;importjavax.crypto.NoSuchPaddingException;importorg.apache.commons.codec.binary.Base64;public classRSAEncrypt {/*** 字节数据转字符串专用集合*/
private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};private static final String PRIVATE_BEGIN = "-----BEGIN PRIVATE KEY-----";private static final String PRIVATE_END = "-----END PRIVATE KEY-----";private static final String PUBLIC_BEGIN = "-----BEGIN PUBLIC KEY-----";private static final String PUBLIC_END = "-----END PUBLIC KEY-----";/*** 1、随机生成密钥对
*
*@paramfilePath 密钥存放目录*/
public voidgenKeyPair(String filePath) {//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = null;try{
keyPairGen= KeyPairGenerator.getInstance("RSA");
}catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}//初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024, newSecureRandom());//生成一个密钥对,保存在keyPair中
KeyPair keyPair =keyPairGen.generateKeyPair();//得到私钥
RSAPrivateKey privateKey =(RSAPrivateKey) keyPair.getPrivate();//得到公钥
RSAPublicKey publicKey =(RSAPublicKey) keyPair.getPublic();try{//得到公钥字符串
Base64 base64 = newBase64();
String publicKeyString= newString(base64.encode(publicKey.getEncoded()));//得到私钥字符串
String privateKeyString = newString(base64.encode(privateKey.getEncoded()));//将密钥对写入到文件
FileWriter pubfw = new FileWriter(filePath + "\\publicKey.pem");
FileWriter prifw= new FileWriter(filePath + "\\privateKey.pem");
BufferedWriter pubbw= newBufferedWriter(pubfw);
BufferedWriter pribw= newBufferedWriter(prifw);
pubbw.write(publicKeyString);
pribw.write(privateKeyString);
pubbw.flush();
pubbw.close();
pubfw.close();
pribw.flush();
pribw.close();
prifw.close();
}catch(Exception e) {
e.printStackTrace();
}
}/*** 2、从本地文件中读取公钥
*
*@parampath 公钥路径
*@return公钥字符串
*@throwsException 异常信息*/
public String loadPublicKeyByFile(String path) throwsException {try{
BufferedReader br= new BufferedReader(newFileReader(path));
String readLine= null;
StringBuilder sb= newStringBuilder();while ((readLine = br.readLine()) != null) {//去除公钥头部底部
if (!readLine.equals(PUBLIC_BEGIN) && !readLine.equals(PUBLIC_END)) {
sb.append(readLine);
}
}
br.close();returnsb.toString();
}catch(IOException e) {throw new Exception("公钥数据流读取错误");
}catch(NullPointerException e) {throw new Exception("公钥输入流为空");
}
}/*** 3、字符串公钥转公钥对象
*
*@parampublicKeyStr 公钥字符串类型
*@return公钥对象
*@throwsException 异常信息*/
publicRSAPublicKey loadPublicKeyByStr(String publicKeyStr)throwsException {try{
Base64 base64= newBase64();byte[] buffer =base64.decode(publicKeyStr);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec= newX509EncodedKeySpec(buffer);return(RSAPublicKey) keyFactory.generatePublic(keySpec);
}catch(NoSuchAlgorithmException e) {throw new Exception("无此算法");
}catch(InvalidKeySpecException e) {throw new Exception("公钥非法");
}catch(NullPointerException e) {throw new Exception("公钥数据为空");
}
}/*** 4、从本地文件中读取私钥
*
*@parampath 私钥文件路径
*@return私钥字符串
*@throwsException 异常信息*/
public String loadPrivateKeyByFile(String path) throwsException {try{
BufferedReader br= new BufferedReader(newFileReader(path));
String readLine= null;
StringBuilder sb= newStringBuilder();while ((readLine = br.readLine()) != null) {//去除私钥头部底部
if (!readLine.equals(PRIVATE_BEGIN) && !readLine.equals(PRIVATE_END)) {
sb.append(readLine);
}else{
}
}
br.close();returnsb.toString();
}catch(IOException e) {throw new Exception("私钥数据读取错误");
}catch(NullPointerException e) {throw new Exception("私钥输入流为空");
}
}/*** 5、字符串公钥转公钥对象
*
*@paramprivateKeyStr 私钥字符串类型
*@return私钥对象
*@throwsException 异常信息*/
publicRSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)throwsException {try{
Base64 base64= newBase64();byte[] buffer =base64.decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec= newPKCS8EncodedKeySpec(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("私钥数据为空");
}
}/*** 6、公钥加密过程
*
*@parampublicKey 公钥
*@paramplainTextData 明文数据
*@return*@throwsException 加密过程中的异常信息*/
public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)throwsException {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);returnoutput;
}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("明文数据已损坏");
}
}/*** 7、私钥加密过程
*
*@paramprivateKey 私钥
*@paramplainTextData 明文数据
*@return*@throwsException 加密过程中的异常信息*/
public byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)throwsException {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);returnoutput;
}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("明文数据已损坏");
}
}/*** 8、私钥解密过程
*
*@paramprivateKey 私钥
*@paramcipherData 密文数据
*@return明文
*@throwsException 解密过程中的异常信息*/
public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)throwsException {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);returnoutput;
}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("密文数据已损坏");
}
}/*** 9、公钥解密过程
*
*@parampublicKey 公钥
*@paramcipherData 密文数据
*@return明文
*@throwsException 解密过程中的异常信息*/
public byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)throwsException {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);returnoutput;
}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("密文数据已损坏");
}
}/*** 10、字节数据转十六进制字符串
*
*@paramdata 输入数据
*@return十六进制内容*/
public String byteArrayToString(byte[] data) {
StringBuilder stringBuilder= newStringBuilder();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(' ');
}
}returnstringBuilder.toString();
}
}