公钥、私钥生成准备工作,基础的帮助类使用java代码生成公钥私钥使用openssl生成公钥私钥 加解密数据签名及验签数据加解密及签名验签测试注意项
公钥、私钥生成
准备工作,基础的帮助类
base64的数据帮助类
代码依赖jar包javabase64-1.3.1.jar
import 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 maskfor (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 blocke.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 blocke.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{// 使用默认RSAcipher = 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{// 使用默认RSAcipher = 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{// 使用默认RSAcipher = 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{// 使用默认RSAcipher = 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 blocke.printStackTrace();}}}
运行结果如下图:
到这里rsa密钥的生成,加密解密就完了
注意项
rsa目前只能加密117字节;解密118字节的数据,如果数据太长,不太适合使用rsa加密方式;可以考虑使用对称加密;然后将对称加密的密钥使用rsa加密;然后将加密后的密钥对数据进行加密。