公钥、私钥生成
准备工作,基础的帮助类
base64的数据帮助类
代码依赖jar包javabase64-1.3.1.jarimport java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import it.sauronsoftware.base64.Base64; /** */ /** * <p> * BASE64编码解码工具包 * </p> * <p> * 依赖javabase64-1.3.1.jar * </p> * */ public class Base64Utils { /** */ /** * 文件读取缓冲区大小 */ private static final int CACHE_SIZE = 1024; /** */ /** * <p> * BASE64字符串解码为二进制数据 * </p> * * @param base64 * @return * @throws Exception */ public static byte[] decode(String base64) throws Exception { return Base64.decode(base64.getBytes()); } /** */ /** * <p> * 二进制数据编码为BASE64字符串 * </p> * * @param bytes * @return * @throws Exception */ public static String encode(byte[] bytes) throws Exception { return new String(Base64.encode(bytes)); } /** */ /** * <p> * 将文件编码为BASE64字符串 * </p> * <p> * 大文件慎用,可能会导致内存溢出 * </p> * * @param filePath * 文件绝对路径 * @return * @throws Exception */ public static String encodeFile(String filePath) throws Exception { byte[] bytes = fileToByte(filePath); return encode(bytes); } /** */ /** * <p> * BASE64字符串转回文件 * </p> * * @param filePath * 文件绝对路径 * @param base64 * 编码字符串 * @throws Exception */ public static void decodeToFile(String filePath, String base64) throws Exception { byte[] bytes = decode(base64); byteArrayToFile(bytes, filePath); } /** */ /** * <p> * 文件转换为二进制数组 * </p> * * @param filePath * 文件路径 * @return * @throws Exception */ public static byte[] fileToByte(String filePath) throws Exception { byte[] data = new byte[0]; File file = new File(filePath); if (file.exists()) { FileInputStream in = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(2048); byte[] cache = new byte[CACHE_SIZE]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } out.close(); in.close(); data = out.toByteArray(); } return data; } /** */ /** * <p> * 二进制数据写文件 * </p> * * @param bytes * 二进制数据 * @param filePath * 文件生成目录 */ public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception { InputStream in = new ByteArrayInputStream(bytes); File destFile = new File(filePath); if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); OutputStream out = new FileOutputStream(destFile); byte[] cache = new byte[CACHE_SIZE]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } out.close(); in.close(); } }
byte数组及hex转换帮助类
import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; /** * byte[] hex数据帮助类 * * @author lupf * */ public class ByteUtil { static byte[] mask = new byte[128]; static { initMask(); } static byte[] asciiMask = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static void initMask() { // init mask for (int i = 0; i <= 9; i++) { mask[i + 48] = (byte) i; } for (int i = 0; i <= 5; i++) { mask[i + 97] = (byte) (10 + i); } for (int i = 0; i <= 5; i++) { mask[i + 65] = (byte) (10 + i); } } public static int[] byte2Bitmap(int b) { int[] bitmap = new int[8]; for (int i = 0; i < 8; i++) { bitmap[i] = ((b >> (8 - i - 1)) & 0x01); } return bitmap; } public static byte[] intToBCD(int n, int balen) { byte[] ret = new byte[balen]; int tmp; for (int i = 1; i <= balen; i++) { tmp = n % 100; ret[balen - i] = (byte) (tmp / 10 * 16 + tmp % 10); n -= tmp; if (n == 0) { break; } n /= 100; } return ret; } public static int bcdToInt(byte[] ba, int idx, int len) { int jinwei = len * 2; int ret = 0; int temp = 0; int pow; int posNum; // 正数 for (int i = 0, n = len; i < n; i++) { pow = pow(10, (jinwei - 1)); posNum = ba[idx + i] >= 0 ? ba[idx + i] : ba[idx + i] + 256; temp = (posNum / 16) * pow + posNum % 16 * pow / 10; ret += temp; jinwei -= 2; } return ret; } public static int pow(int x, int y) { int n = x; for (int i = 1; i < y; i++) { n *= x; } return n; } public static byte[] hexStr2Byte(String hex) { int len = (hex.length() / 2); byte[] result = new byte[len]; char[] achar = hex.toCharArray(); for (int i = 0; i < len; i++) { int pos = i * 2; result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1])); } return result; } public static int revAsciiHexToInt(byte[] ah) { int ret = 0; for (int i = 0; i < ah.length / 2; i++) { int hex = (mask[ah[i * 2]] << 4) + (mask[ah[i * 2 + 1]]); ret += (hex << (8 * i)); } return ret; } public static int revHexToInt(byte[] data, int off, int len) { int ret = 0; for (int i = 0; i < len; i++) { ret += (data[off + i] & 0xff) << (8 * i); } return ret; } public static int revAsciiHexToInt(byte[] ah, int off, int len) { int ret = 0; for (int i = 0, n = len / 2; i < n; i++) { int hex = (mask[ah[i * 2 + off]] << 4) + (mask[ah[i * 2 + off + 1]]); ret += (hex << (8 * i)); } return ret; } public static byte[] intToRevAsciiHex(int value, int hexlen) { byte[] ret = new byte[hexlen * 2]; for (int i = 0; i < hexlen; i++) { if (value > 0) { ret[i * 2] = asciiMask[((value & 0xf0) >> 4)]; ret[i * 2 + 1] = asciiMask[(value & 0xf)]; value >>= 8; } else { ret[i * 2] = '0'; ret[i * 2 + 1] = '0'; } } return ret; } public static String intToRevHexString(int value, int hexlen) { byte[] ret = new byte[hexlen]; for (int i = 0; i < hexlen; i++) { ret[i] = (byte) (value & 0xff); value >>= 8; if (value == 0) break; } return hexToStr(ret); } public static byte[] intToAsciiHex(int value, int len) { byte[] ret = new byte[len * 2]; for (int i = 0; i < len; i++) { ret[i * 2] = asciiMask[((value & 0xf0) >> 4)]; ret[i * 2 + 1] = asciiMask[value & 0xf]; value >>= 8; } return ret; } public static byte[] intToHex(int value, int len) { byte[] ret = new byte[len]; for (int i = 0; i < len; i++) { ret[i] = (byte) ((value >> 8 * (len - i - 1)) & 0xff); } return ret; } public static byte[] intToRevHex(int value, int len) { byte[] ret = new byte[len]; for (int i = 0; i < len; i++) { ret[i] = (byte) (value & 0xff); value >>= 8; } return ret; } public static int hexToInt(byte[] buf, int idx, int len) { int ret = 0; final int e = idx + len; for (int i = idx; i < e; ++i) { ret <<= 8; ret |= buf[i] & 0xFF; } return ret; } public static int hexToInt(byte[] buf) { return hexToInt(buf, 0, buf.length); } public static String hexToStr(byte[] buf) { return hexToStr(buf, 0, buf.length); } public static String hexToStr(byte[] buf, int idx, int len) { StringBuffer sb = new StringBuffer(); int n; for (int i = 0; i < len; i++) { n = buf[i + idx] & 0xff; if (n < 0x10) { sb.append("0"); } sb.append(Integer.toHexString(n)); } return sb.toString(); } private static byte toByte(char c) { return mask[c]; } public static String strToHex(String str) { try { byte[] bytes = str.getBytes("GBK"); StringBuilder sb = new StringBuilder(bytes.length * 2); // 转换hex编码 for (byte b : bytes) { sb.append(Integer.toHexString(b + 0x800).substring(1)); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } }
使用java代码生成公钥私钥
/**
* 随机生成密钥对
*
* @param filePath
* 本地用于存放密钥的路径,如E:/rsa/;那么生成的密钥就会保存在指定的路径下
*/
public static void genKeyPair(String filePath)
{
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
File file = new File(filePath);
if (!file.exists())
file.mkdirs();
KeyPairGenerator keyPairGen = null;
try
{
keyPairGen = KeyPairGenerator.getInstance("RSA");
}
catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// 初始化密钥对生成器,密钥大小
keyPairGen.initialize(1024, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
try
{
// 得到公钥字符串
String publicKeyString = Base64Utils.encode(publicKey.getEncoded());
// 得到私钥字符串
String privateKeyString = Base64Utils.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();
}
}
执行以上代码,即可在指定的文件目录下得到我们需要的公钥及私钥,如下图:
使用openssl生成公钥私钥
资源下载
这里的openssl是下载的支付宝开放平台下共享的资源,下载入口,进入之后有如下的界面,这里下载的window的版本:
或者百度云下载
解压之后,进入到openssl目录,如下图:
密钥生成
- 第一步:运行“生成公钥私钥转换PCKS8.bat”
- 第二步:运行“私钥转换PCKS8.bat”
- 第三步:同级目录下会出现下图中三个文件
红框中的2个文件即对应的公钥和私钥,使用notepad++或者UE查看即可。 - 第四步:需注意以下情况
通过此方法生成的密钥是以下形式的
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP0TVM3bg80cqhA1XcqLCEi3MQ
bWZYf5Zmwd2mA1C5DbNR1OtsPqemJsJkdTDx4OSuvvUhxHEXJbNPoWx+1ktV+5Cv
hiytGjwQ5OKWOw9+Iq4Q10IzucgiKMe2NVDK1j9TnNK5SteSw+TUUgaNKS+hNPUq
vX5jhQDvadE51JIO5wIDAQAB
-----END PUBLIC KEY-----
其中—–BEGIN PUBLIC KEY—–和—–END PUBLIC KEY—–为密钥的头和尾,实际使用过程中该部分需要去掉,实际的密钥如下:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP0TVM3bg80cqhA1XcqLCEi3MQbWZYf5Zmwd2mA1C5DbNR1OtsPqemJsJkdTDx4OSuvvUhxHEXJbNPoWx+1ktV+5CvhiytGjwQ5OKWOw9+Iq4Q10IzucgiKMe2NVDK1j9TnNK5SteSw+TUUgaNKS+hNPUqvX5jhQDvadE51JIO5wIDAQAB
加解密
这里的加解密使用的是通过java代码生成的密钥进行操作及测试
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
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;
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' };
/**
* 随机生成密钥对
*
* @param filePath
* 本地用于存放密钥的路径,如E:/rsa/;那么生成的密钥就会保存在指定的路径下
*/
public static void genKeyPair(String filePath)
{
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
File file = new File(filePath);
if (!file.exists())
file.mkdirs();
KeyPairGenerator keyPairGen = null;
try
{
keyPairGen = KeyPairGenerator.getInstance("RSA");
}
catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
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 = Base64Utils.encode(publicKey.getEncoded());
// 得到私钥字符串
String privateKeyString = Base64Utils.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
{
byte[] buffer = Base64Utils.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
{
byte[] buffer = Base64Utils.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();
}
}
数据签名及验签
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签名,得到base64字符串
*
* @param content
* 待签名数据
* @param privateKey
* 商户私钥
* @param encode
* 字符集编码
* @return 签名值,base64字符串
*/
public static String signBase64(String content, String privateKey, String encode)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Utils.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 Base64Utils.encode(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* RSA签名,得到base64字符串
*
* @param content
* 待签名数据
* @param privateKey
* 商户私钥
* @return 签名值,base64字符串
*/
public static String signBase64(String content, String privateKey)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Utils.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 Base64Utils.encode(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* RSA验签名检查,数据源为base64字符串
*
* @param content
* 待签名数据,base64字符串
* @param sign
* 签名值
* @param publicKey
* 分配给开发商公钥
* @param encode
* 字符集编码
* @return 布尔值
*/
public static boolean doCheckBase64(String content, String sign, String publicKey, String encode)
{
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64Utils.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(Base64Utils.decode(sign));
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
/**
* RSA验签名检查,数据源为base64字符串
*
* @param content
* 待签名数据,base64字符串
* @param sign
* 签名值
* @param publicKey
* 分配给开发商公钥
* @return 布尔值
*/
public static boolean doCheckBase64(String content, String sign, String publicKey)
{
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64Utils.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(Base64Utils.decode(sign));
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
/**
* RSA签名,得到Hex字符串
*
* @param content
* 待签名数据
* @param privateKey
* 商户私钥
* @param encode
* 字符集编码
* @return 签名值,Hex字符串
*/
public static String signHex(String content, String privateKey, String encode)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Utils.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 ByteUtil.hexToStr(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* RSA签名,得到Hex字符串
*
* @param content
* 待签名数据
* @param privateKey
* 商户私钥
* @return 签名值,Hex字符串
*/
public static String signHex(String content, String privateKey)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Utils.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 ByteUtil.hexToStr(signed);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* RSA验签名检查,数据源为Hex字符串
*
* @param content
* 待签名数据,Hex字符串
* @param sign
* 签名值
* @param publicKey
* 分配给开发商公钥
* @param encode
* 字符集编码
* @return 布尔值
*/
public static boolean doCheckHex(String content, String sign, String publicKey, String encode)
{
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64Utils.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(ByteUtil.hexStr2Byte(sign));
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
/**
* RSA验签名检查,数据源为Hex字符串
*
* @param content
* 待签名数据,Hex字符串
* @param sign
* 签名值
* @param publicKey
* 分配给开发商公钥
* @return 布尔值
*/
public static boolean doCheckHex(String content, String sign, String publicKey)
{
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64Utils.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(ByteUtil.hexStr2Byte(sign));
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
}
数据加解密及签名验签测试
public class MainTest
{
public static void main(String[] args)
{
try
{
String filepath = "E:/rsa/";
RSAEncrypt.genKeyPair(filepath);
String privateKey = RSAEncrypt.loadPrivateKeyByFile(filepath);
String publicKey = RSAEncrypt.loadPublicKeyByFile(filepath);
System.out.println("私钥:" + privateKey);
System.out.println("公钥:" + publicKey);
System.out.println("--------------公钥加密私钥解密过程-------------------");
String data = "rsa公钥加密私钥解密过程";
// 公钥加密过程
byte[] cipherData = RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(publicKey), data.getBytes());
// base64的密文数据
String cipher = Base64Utils.encode(cipherData);
// hex的密文数据
String cipherHex = ByteUtil.hexToStr(cipherData);
// 私钥解密base64的密文过程
byte[] resBase64 = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(privateKey), Base64Utils.decode(cipher));
String restrBase64 = new String(resBase64);
// 私钥解密hex的密文过程
byte[] resHex = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(privateKey), ByteUtil.hexStr2Byte(cipherHex));
String restrHex = new String(resHex);
System.out.println("原文:" + data);
System.out.println("加密(base64):" + cipher);
System.out.println("加密(hex):" + cipherHex);
System.out.println("解密(base64):" + restrBase64);
System.out.println("解密(hex):" + restrHex);
System.out.println();
System.out.println("--------------私钥加密公钥解密过程-------------------");
data = "rsa私钥加密公钥解密过程";
// 私钥加密过程
cipherData = RSAEncrypt.encrypt(RSAEncrypt.loadPrivateKeyByStr(privateKey), data.getBytes());
cipher = Base64Utils.encode(cipherData);
// 公钥解密过程
resBase64 = RSAEncrypt.decrypt(RSAEncrypt.loadPublicKeyByStr(publicKey), Base64Utils.decode(cipher));
restrBase64 = new String(resBase64);
System.out.println("原文:" + data);
System.out.println("加密:" + cipher);
System.out.println("解密:" + restrBase64);
System.out.println();
System.out.println("--------------签名及验签测试-----------------------");
data = "rsa签名及验签测试";
System.out.println("签名源数据:" + data);
String singData = RSASignature.signBase64(data, privateKey);
System.out.println("使用私钥对data数据签名,得到base64的签名数据为:" + singData);
boolean ckeckVa = RSASignature.doCheckBase64(data, singData, publicKey);
System.out.println("使用公钥对签名后的base64数据进行验证的结果为:" + ckeckVa);
System.out.println("");
singData = RSASignature.signHex(data, privateKey);
System.out.println("使用私钥对data数据签名,得到hex的签名数据为:" + singData);
ckeckVa = RSASignature.doCheckHex(data, singData, publicKey);
System.out.println("使用公钥对签名后的hex数据进行验证的结果为:" + ckeckVa);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果如下图:
到这里rsa密钥的生成,加密解密就完了
注意项
rsa目前只能加密117字节;解密118字节的数据,如果数据太长,不太适合使用rsa加密方式;可以考虑使用对称加密;然后将对称加密的密钥使用rsa加密;然后将加密后的密钥对数据进行加密。