123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package com.szwl.model.utils;
- import com.szwl.model.utils.constants.Algorithm;
- import com.szwl.model.utils.constants.CommonConst;
- import com.szwl.model.utils.exceptions.JPException;
- import javax.crypto.Cipher;
- import java.io.ByteArrayOutputStream;
- import java.security.*;
- import java.security.spec.PKCS8EncodedKeySpec;
- import java.security.spec.X509EncodedKeySpec;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * RSA加解密的工具类
- * @author chenyf
- * @date 2018-12-15
- */
- public class RSAUtil {
- public static final String DEFAULT_ENCRYPT_ALGORITHM = "RSA/ECB/PKCS1Padding";
- public static final String SIGNATURE_ALGORITHM_SHA1 = "SHA1withRSA";
- public static final String SIGNATURE_ALGORITHM_MD5 = "MD5withRSA";
- public static final int KEY_SIZE = 1024;
- public static final String PUBLIC_KEY = "publicKey";
- public static final String PRIVATE_KEY = "privateKey";
- /**
- /**
- * RSA最大加密明文大小
- */
- private static final int MAX_ENCRYPT_BLOCK = 116;
- /**
- /**
- * RSA最大解密密文大小
- */
- private static final int MAX_DECRYPT_BLOCK = 128;
- /**
- * 生成公私密钥对
- * @return
- * @throws Exception
- */
- public static Map<String, String> genKeyPair() throws Exception {
- KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(Algorithm.RSA);
- keyPairGen.initialize(KEY_SIZE);
- KeyPair keyPair = keyPairGen.generateKeyPair();
- final Map<String, String> keyMap = new HashMap<String, String>(2);
- keyMap.put(PUBLIC_KEY, CodeUtil.base64Encode(keyPair.getPublic().getEncoded()));
- keyMap.put(PRIVATE_KEY, CodeUtil.base64Encode(keyPair.getPrivate().getEncoded()));
- return keyMap;
- }
- /**
- * 生成RSA签名串
- * @param data 需要生成签名串的数据
- * @param mchPrivateKey 商户私钥
- * @return
- * @throws JPException
- */
- public static String sign(String data, String mchPrivateKey, boolean isSha) throws JPException {
- try {
- byte[] dataBytes = data.getBytes(CommonConst.ENCODING_UTF_8);
- byte[] keyBytes = CodeUtil.base64Decode(mchPrivateKey);
- String algorithm = isSha ? SIGNATURE_ALGORITHM_SHA1 : SIGNATURE_ALGORITHM_MD5;
- PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
- PrivateKey priKey = KeyFactory.getInstance(Algorithm.RSA).generatePrivate(pkcs8KeySpec);
- Signature signature = Signature.getInstance(algorithm);
- signature.initSign(priKey);
- signature.update(dataBytes);
- return HEXUtil.encode(CodeUtil.base64Encode(signature.sign()));
- }catch (Throwable e){
- throw new JPException("生成RSA签名失败", e);
- }
- }
- /**
- * 验证RSA签名串
- * @param data 需要验签的数据
- * @param jpPublicKey 汇聚公钥
- * @param sign 汇聚返回的签名串
- * @return
- * @throws JPException
- */
- public static boolean verify(String data, String jpPublicKey, String sign, boolean isSha) throws JPException {
- try {
- byte[] dataBytes = data.getBytes(CommonConst.ENCODING_UTF_8);
- byte[] signBytes = CodeUtil.base64Decode(HEXUtil.decode(sign));
- String algorithm = isSha ? SIGNATURE_ALGORITHM_SHA1 : SIGNATURE_ALGORITHM_MD5;
- PublicKey publicK = getPublicKey(jpPublicKey);
- Signature signature = Signature.getInstance(algorithm);
- signature.initVerify(publicK);
- signature.update(dataBytes);
- return signature.verify(signBytes);
- }catch (Throwable e){
- throw new JPException("RSA验签失败", e);
- }
- }
- /**
- * 使用RSA进行加密
- * @param data 需要加密的数据
- * @param jpPublicKey 汇聚公钥
- * @return
- */
- public static String encrypt(String data, String jpPublicKey) throws JPException {
- try{
- byte[] dataBytes = data.getBytes(CommonConst.ENCODING_UTF_8);
- dataBytes = doCipher(dataBytes, jpPublicKey, true);
- return HEXUtil.encode(CodeUtil.base64Encode(dataBytes));
- }catch(Throwable e){
- throw new JPException("RSA加密失败", e);
- }
- }
- /**
- * 使用RSA进行解密
- * @param data 需要解密的数据
- * @param mchPrivateKey 商户私钥
- * @return
- */
- public static String decrypt(String data, String mchPrivateKey) throws JPException {
- try{
- byte[] dataBytes = CodeUtil.base64Decode(HEXUtil.decode(data));
- dataBytes = doCipher(dataBytes, mchPrivateKey, false);
- return new String(dataBytes, CommonConst.ENCODING_UTF_8);
- }catch(Throwable e){
- throw new JPException("RSA解密失败", e);
- }
- }
- private static byte[] doCipher(byte[] dataBytes, String keyStr, boolean isEncrypt) throws Exception{
- Key key;
- Cipher cipher;
- int maxBlock;
- if(isEncrypt){
- maxBlock = MAX_ENCRYPT_BLOCK;
- key = getPublicKey(keyStr);
- cipher = Cipher.getInstance(DEFAULT_ENCRYPT_ALGORITHM);
- cipher.init(Cipher.ENCRYPT_MODE, key);
- }else{
- maxBlock = MAX_DECRYPT_BLOCK;
- byte[] keyBytes = CodeUtil.base64Decode(keyStr);
- PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory keyFactory = KeyFactory.getInstance(Algorithm.RSA);
- Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
- cipher = Cipher.getInstance(keyFactory.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE, privateK);
- }
- int offSet = 0, i = 0, inputLen = dataBytes.length;
- byte[] cache;
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- try{
- // 对数据分段加密/解密
- while (inputLen - offSet > 0) {
- if (inputLen - offSet > maxBlock) {
- cache = cipher.doFinal(dataBytes, offSet, maxBlock);
- } else {
- cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
- }
- out.write(cache, 0, cache.length);
- i++;
- offSet = i * maxBlock;
- }
- return out.toByteArray();
- } finally {
- out.close();
- }
- }
- private static PublicKey getPublicKey(String publicKey) throws Exception{
- byte[] keyBytes = CodeUtil.base64Decode(publicKey);
- X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
- KeyFactory keyFactory = KeyFactory.getInstance(Algorithm.RSA);
- return keyFactory.generatePublic(x509KeySpec);
- }
- }
|