一、前言
基于RSA的公钥对分配生成公钥(public_key)、私钥(private_key),用户或服务消费方通过私钥对数据加签,服务提供方通过对应的公钥进行解签验证,为了保证数据安全性基于AES对密钥进行高位数加密合成和敏感数据的保护。
二、代码示例
1.AESDataCipherUtil类 - 对数据内容进行加解密工具类,具体代码如下
import javax.crypto.Cipher;@b@import javax.crypto.KeyGenerator;@b@import javax.crypto.SecretKey;@b@import javax.crypto.spec.SecretKeySpec;@b@@b@public class AESDataCipherUtil {@b@@b@ //密钥算法 @b@ private static final String KEY_ALGORITHM = "AES"; @b@ @b@ //加解密算法/工作模式/填充方式@b@ private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; @b@ @b@ private static final int KEYSIZE = 128;@b@ @b@ /** @b@ * 生成密钥 @b@ */ @b@ public static String initAesKey() throws Exception{@b@ try{@b@ KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM); //实例化密钥生成器 @b@ kg.init(KEYSIZE); //初始化密钥生成器:AES要求密钥长度为128,192,256位 @b@ SecretKey secretKey = kg.generateKey(); //生成密钥 @b@ @b@ byte[] keyb = secretKey.getEncoded();@b@ String key = byteToHexString(keyb); // 二进制转换成十六进制@b@@b@ System.out.println(key);@b@ @b@ return key; @b@ }catch (Exception e) {@b@ throw e;@b@ }@b@ @b@ } @b@ @b@ @b@ /** @b@ * 加密@b@ * @param String data 待加密数据 @b@ * @param String key 密钥 @b@ * @return String result 加密后的数据 @b@ * */ @b@ public static String encrypt(String data, String key) throws Exception{ @b@ try{@b@ byte[] resultb = encrypt(data, hexStringToByte(key)); // 加密后数据 @b@ String result = byteToHexString(resultb); // 转成十六进制@b@ return result; // 加密后数据 @b@ }catch (Exception e){@b@ throw e;@b@ }@b@ }@b@ @b@ @b@ /** @b@ * 加密@b@ * @param String data 待加密数据 @b@ * @param byte[] key 密钥 @b@ * @return byte[] encryptData 加密后的数据 @b@ * */ @b@ public static byte[] encrypt(String data, byte[] keyb) throws Exception{ @b@ @b@ try{@b@ SecretKeySpec sKeySpec = new SecretKeySpec(keyb, KEY_ALGORITHM);@b@ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //实例化Cipher对象,它用于完成实际的加密操作 @b@ cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); //初始化Cipher对象,设置为加密模式 @b@ @b@ byte[] result = cipher.doFinal(data.getBytes("utf-8")); // 加密数据@b@ return result; // 加密后数据 @b@ }catch (Exception e){@b@ throw e;@b@ }@b@ @b@ } @b@ @b@ /** @b@ * 解密@b@ * @param String data 待解密数据 (十六进制)@b@ * @param String key 密钥 (十六进制)@b@ * @return String result 解密后的数据 @b@ * */ @b@ public static String decrypt(String data, String key) throws Exception{ @b@ @b@ try{@b@ byte[] datab = hexStringToByte(data);@b@ byte[] keyb = hexStringToByte(key);@b@ @b@ return decrypt(datab, keyb); // 解密后数据 @b@ }catch (Exception e){@b@ throw e;@b@ }@b@ @b@ } @b@ @b@ @b@ /** @b@ * 解密 @b@ * @param byte[] data 待解密数据 (十六进制)@b@ * @param byte[] keyb 密钥 @b@ * @return String result 解密后的数据 @b@ * */ @b@ public static String decrypt(byte[] datab, byte[] keyb) throws Exception{ @b@ @b@ try{@b@ SecretKeySpec sKeySpec = new SecretKeySpec(keyb, KEY_ALGORITHM);@b@ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //实例化Cipher对象,它用于完成实际的加密操作 @b@ cipher.init(Cipher.DECRYPT_MODE, sKeySpec); //初始化Cipher对象,设置为加密模式 @b@ @b@ byte[] resultb = cipher.doFinal(datab); // 解密@b@ @b@ return new String(resultb); // 解密后数据 @b@ }catch (Exception e){@b@ throw e;@b@ }@b@ @b@ } @b@@b@ @b@ /** @b@ * 二进制byte[]转十六进制string @b@ */ @b@ public static String byteToHexString(byte[] bytes){ @b@ StringBuffer sb = new StringBuffer(); @b@ for (int i = 0; i < bytes.length; i++) { @b@ String strHex=Integer.toHexString(bytes[i]); @b@ if(strHex.length() > 3){ @b@ sb.append(strHex.substring(6)); @b@ } else { @b@ if(strHex.length() < 2){ @b@ sb.append("0" + strHex); @b@ } else { @b@ sb.append(strHex); @b@ } @b@ } @b@ } @b@ return sb.toString(); @b@ }@b@ @b@ /** @b@ * 十六进制string转二进制byte[] @b@ */ @b@ public static byte[] hexStringToByte(String s) { @b@ byte[] baKeyword = new byte[s.length() / 2]; @b@ for (int i = 0; i < baKeyword.length; i++) { @b@ try { @b@ baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); @b@ } catch (Exception e) { @b@ System.out.println("十六进制转byte发生错误!!!"); @b@ e.printStackTrace(); @b@ } @b@ } @b@ return baKeyword; @b@ } @b@@b@ @b@ public static void main(String[] args) throws Exception { @b@ try{@b@ @b@ // 生成密钥@b@ String key = initAesKey();@b@ System.out.println(key);@b@ @b@ // 加密原串@b@ String source = "小木人印象xwood.net"; @b@ System.out.println("原文: "); @b@ System.out.println(source);@b@ @b@ // AES加密@b@ String encryptData = encrypt(source, key); @b@ System.out.println("加密密文 : "); @b@ System.out.println(encryptData); @b@ @b@ // AES解密@b@ String decryptData = decrypt(encryptData, key); @b@ System.out.println("解密原文: "); @b@ System.out.println(decryptData); @b@ @b@ }catch (Exception e){@b@ System.out.println(e.getMessage());@b@ }@b@ @b@ }@b@@b@}
控制台输出结果为
39b329d41bff57226a4a4c45ec31170c@b@39b329d41bff57226a4a4c45ec31170c@b@原文: @b@小木人印象xwood.net@b@加密密文 : @b@c68314c09d1560c5e6259858bab573671421c4d61d8a8f435665533d2d6e3ba1@b@解密原文: @b@小木人印象xwood.net
2.RSADataSignUtil - 公私钥加签验签工具类,具体代码如下
import java.security.KeyFactory;@b@import java.security.PrivateKey;@b@import java.security.PublicKey;@b@import java.security.Signature;@b@import java.security.spec.PKCS8EncodedKeySpec;@b@import java.security.spec.X509EncodedKeySpec;@b@@b@public class RSADataSignUtil {@b@ @b@ private static final String KEY_ALGORITHM = "RSA";@b@@b@ private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";@b@@b@ /**@b@ * 加签数据@b@ * @b@ * @param String@b@ * data 待加签数据@b@ * @param String@b@ * privateKey 私钥@b@ * @return String signedData 加签值(十六进制)@b@ * */@b@ public static String sign(String data, String privateKey) throws Exception {@b@ try {@b@ byte[] signData = sign(data, hexStringToByte(privateKey));@b@@b@ return byteToHexString(signData);@b@@b@ } catch (Exception e) {@b@ throw new Exception("signature.sign.error : " + e.getMessage());@b@ }@b@ }@b@@b@ /**@b@ * 加签数据@b@ * @b@ * @param String@b@ * data 待加签数据@b@ * @param byte[] privateKey 私钥@b@ * @return byte[] signedData@b@ * */@b@ public static byte[] sign(String data, byte[] privateKeyBytes)@b@ throws Exception {@b@@b@ try {@b@ PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(@b@ privateKeyBytes);@b@ KeyFactory keyf = KeyFactory.getInstance(KEY_ALGORITHM);@b@ PrivateKey key = keyf.generatePrivate(priPKCS8);@b@@b@ // 进行签名服务@b@ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);@b@ signature.initSign(key);@b@ signature.update(data.getBytes());@b@ byte[] signData = signature.sign();@b@@b@ // 返回签名结果@b@ return signData;@b@ } catch (Exception e) {@b@ throw new Exception("signature.sign.error : " + e.getMessage());@b@ }@b@ }@b@@b@ /**@b@ * 根据对签名数据使用签名者的公钥来解密后验证是否与原数据相同。从而确认用户签名正确@b@ * @b@ * @param String@b@ * data 被签名数据@b@ * @param String@b@ * signStr 使用该用户的私钥生成的已签名数据(十六进制)@b@ * @param String@b@ * publicKey 公钥(十六进制)@b@ * @return true或false,验证成功为true。@b@ * @throws Exception@b@ */@b@ public static boolean verify(String data, String signStr, String publicKey)@b@ throws Exception {@b@ try {@b@ return verify(data, hexStringToByte(signStr),@b@ hexStringToByte(publicKey));@b@ } catch (Exception e) {@b@ throw new Exception("signature.verify.error : " + e.getMessage());@b@ }@b@ }@b@@b@ /**@b@ * 根据对签名数据使用签名者的公钥来解密后验证是否与原数据相同。从而确认用户签名正确@b@ * @b@ * @param String@b@ * data 被签名数据@b@ * @param byte[] signStr 使用该用户的私钥生成的已签名数据@b@ * @param String@b@ * publicKey 公钥@b@ * @return true或false,验证成功为true。@b@ * @throws Exception@b@ */@b@ public static boolean verify(String data, byte[] signStrBytes,@b@ byte[] publicKeyBytes) throws Exception {@b@ try {@b@ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);@b@ PublicKey pubKey = keyFactory@b@ .generatePublic(new X509EncodedKeySpec(publicKeyBytes));@b@@b@ // 进行验证签名服务@b@ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);@b@ signature.initVerify(pubKey);@b@ signature.update(data.getBytes());@b@ return signature.verify(signStrBytes);@b@ } catch (Exception e) {@b@ throw new Exception("signature.verify.error : " + e.getMessage());@b@ }@b@ }@b@@b@ /**@b@ * 二进制byte[]转十六进制string@b@ */@b@ public static String byteToHexString(byte[] bytes) {@b@ StringBuffer sb = new StringBuffer();@b@ for (int i = 0; i < bytes.length; i++) {@b@ String strHex = Integer.toHexString(bytes[i]);@b@ if (strHex.length() > 3) {@b@ sb.append(strHex.substring(6));@b@ } else {@b@ if (strHex.length() < 2) {@b@ sb.append("0" + strHex);@b@ } else {@b@ sb.append(strHex);@b@ }@b@ }@b@ }@b@ return sb.toString();@b@ }@b@@b@ /**@b@ * 十六进制string转二进制byte[]@b@ */@b@ public static byte[] hexStringToByte(String s) throws Exception {@b@ byte[] baKeyword = new byte[s.length() / 2];@b@ for (int i = 0; i < baKeyword.length; i++) {@b@ try {@b@ baKeyword[i] = (byte) (0xff & Integer.parseInt(@b@ s.substring(i * 2, i * 2 + 2), 16));@b@ } catch (Exception e) {@b@ System.out.println("十六进制转byte发生错误!!!");@b@ throw (e);@b@ }@b@ }@b@ return baKeyword;@b@ }@b@@b@ public static void main(String[] args) throws Exception {@b@ try {@b@@b@ // 生成 公私密钥@b@ RSAKeyStoreUtil.genKey();@b@@b@ // 测试用@b@ String private_key = "30820277020100300D06092A864886F70D0101010500048202613082025D0201000281810088E387781D6B112B76D6353877AFA271B3F7B73EC149ADC984574F8B37F9BE7F390D7B22F1E36640912C88F6285B2878176D8108AB031CE6ECF21186F8AED9B2262DEC9CC1D0D83EB242A90BC2CEAAB168BB729F13438A75F842D6361F51B27BFFBAF3091EB18E9DDA773EA19DE994A424478BB1F7C0C705C7CDC238423A08A702030100010281803DFCB282ACE7A7EDC3B17A8628848B0DEC0DF797DE552BF23E107F7FAE8854402E28B1A30060161494E8D2D88D2BC266A74D3A0A1FCE980EE62B33CEA7DC1DCDC7BA3E024359C2DA5C4F1F60E22D7616710F093441E0B5355D739F900F4458B6AF0C2EDA987C794623719C6E9A3E62B9109C3DD67D6C1E5042F5283A1CAE0291024100DA4BCC2A65309A1EF16C347CDE559875DBC501DD07DFA99D75A5A7AEE7B1C0971C9950A6D7F38B10493B46C2F746197A4D2EBB407014D59EA925F444F168083F024100A08837D1C3BC1CB8E903B19F8072F629ED10295B382914D169ED069BDC7C422923CD9FE025A493C72652BBDF630F9C65763232822F57B80D7078B1F6F7242599024100B9386D205FC19053C6F6CFC64F84031BA580906731C21611D37BDE3E6ABB08B56EFFAB4E1597C09BEDF70CC06ABD20EB03C82DFBABDE11AF50C8326DB903535302403E64B34D544648E395AD59DC24908A1CC187068BEDC809CF5ADC45354EFCFCBA00B06AF333AE43C1A3A38461CE9EC2AAACC5D5DBC38AD47E64B88472F89B9401024100BD85C9BFE53C1757FB091C43EB265BA35B9D4EEBB0EF703472E3F7E3D3D94F727F90B84875D591EFB7E9438A6ADA5F49097904BCDB1F9F68B6E552399252F401";@b@ String public_key = "30819F300D06092A864886F70D010101050003818D003081890281810088E387781D6B112B76D6353877AFA271B3F7B73EC149ADC984574F8B37F9BE7F390D7B22F1E36640912C88F6285B2878176D8108AB031CE6ECF21186F8AED9B2262DEC9CC1D0D83EB242A90BC2CEAAB168BB729F13438A75F842D6361F51B27BFFBAF3091EB18E9DDA773EA19DE994A424478BB1F7C0C705C7CDC238423A08A70203010001";@b@@b@ String source = "20170629;9999;100010";@b@ System.out.println("原文: ");@b@ System.out.println(source);@b@@b@ // 加签@b@ String signStr = sign(source, private_key);@b@@b@ System.out.println("加签: ");@b@ System.out.println(signStr);@b@@b@ // 验签@b@ boolean flag = verify(source, signStr, public_key);@b@ System.out.println("验签结果 : ");@b@ System.out.println(flag);@b@@b@ } catch (Exception e) {@b@ System.out.println(e.getMessage());@b@ }@b@@b@ }@b@@b@}
控制台输出结果如下
keys-gen public_key:30819F300D06092A864886F70D010101050003818D00308189028181008B73403EB411F8CB4670EB004D6C456E2871ECFF14FB38CD0B4714F2C4B45F530DE91904B8A1D53D7057890EAA3308DB0F56D1622F42053F75700A26E3D834036C405377240169DA2B0365DDDAFE42E347F6585B7BE37C56C1303626BBCC866BFDBE3D446BDDAE1665DF415C0AEC5ACFC99CEC7F01118AA98BDBF70BB24340B50203010001@b@keys-gen private_key:30820276020100300D06092A864886F70D0101010500048202603082025C020100028181008B73403EB411F8CB4670EB004D6C456E2871ECFF14FB38CD0B4714F2C4B45F530DE91904B8A1D53D7057890EAA3308DB0F56D1622F42053F75700A26E3D834036C405377240169DA2B0365DDDAFE42E347F6585B7BE37C56C1303626BBCC866BFDBE3D446BDDAE1665DF415C0AEC5ACFC99CEC7F01118AA98BDBF70BB24340B5020301000102818060AE6603531B06B0004577587D552C89E436A04675C87B2805C2A16E731C4EDEA94D4BD02F25DC4EBD5DA3236CB2F757D139B2EF6CAE4C2F23FFAABA2DCB8EBB2E1CE01716216BB18D0DF8988ACFC1B1F17F7C4E0392E8B193C84DC67D917925D4648C941F86E5F36191C8C910A1889991D6B1C4FABD98F0A0243B6505EFFF01024100CB0E95CB1555ABB8B72242BE3F1CC7E127FA0CE4BFE346940767C2E70DA44AAEAC02622430B95BA734E98E92374B39E16D3A9AFED5F3E74EE06C25290F4AD1C1024100AFCF1D1084DF7CEA4E887F27A2A3DE31AA3EEA14754966ED66E358379672E1D3E18F96A211EAA0181F98241359AE11AC54DDD81EAD6B72A6AF7D12F5658343F5024034F439C63B6B1B1C51CE027FE0AF9DC4AF0B3BBF8FF73259BA50A9F85D8B61DA898B1992FC8DEA4401BD82EBC8B5BA837A5BD53DEE07EC639A8D3967AAD0454102407938918DC65062CD1C0139CB9674EECBC7DB418381AB6EF0DA347FAB346D5A10C2424356D48BB67F6BA97796700B79DC1D5829A05D6AECCEC9C9AFBCCC95C9D1024100956F0DECEF780A5E47333A965D72149D43C505A5F001471511248BA29D7BF3CEA257BB86D930A704B088B58F8A06EA25D37906BFBCFAC21D7A97BE77B861F053@b@原文: @b@20170629;9999;100010@b@加签: @b@24e5b22e586a8e1ae227c009e89b59515eeb4c0ffeb6ace4a77360432245ed6c8e9eef8a4f5afbabe62801c070571267958789ed23c019980f2ab009df465738c67f2f709c49bbd2fcd5afaf1eff969f9b74fa503984bfdac27b54c0ffd61e5be56ab86678bfc4f034f42b31d837dbc6b23deba5860ffc83657c9d481e7281b5@b@验签结果 : @b@true
3. RSAKeyStoreUtil - 密钥对生成类,通过aes对数据进行加密,用加密后的数据通过私钥加签,通过公钥解签验证,然后在解密数据,rsa+aes的完整应用示例
import java.security.KeyFactory;@b@import java.security.KeyPair;@b@import java.security.KeyPairGenerator;@b@import java.security.SecureRandom;@b@import java.security.interfaces.RSAPrivateKey;@b@import java.security.interfaces.RSAPublicKey;@b@import java.security.spec.PKCS8EncodedKeySpec;@b@import java.security.spec.X509EncodedKeySpec;@b@import java.util.HashMap;@b@import java.util.Map;@b@import javax.crypto.Cipher;@b@import org.apache.commons.lang.ArrayUtils;@b@import com.alibaba.fastjson.JSON;@b@import com.alibaba.fastjson.JSONObject;@b@@b@public class RSAKeyStoreUtil {@b@ @b@private static final String KEY_ALGORITHM = "RSA";@b@ @b@ private static final char[] bcdLookup = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };@b@ @b@ private static String publicKey = "30819F300D06092A864886F70D010101050003818D003081890281810088E387781D6B112B76D6353877AFA271B3F7B73EC149ADC984574F8B37F9BE7F390D7B22F1E36640912C88F6285B2878176D8108AB031CE6ECF21186F8AED9B2262DEC9CC1D0D83EB242A90BC2CEAAB168BB729F13438A75F842D6361F51B27BFFBAF3091EB18E9DDA773EA19DE994A424478BB1F7C0C705C7CDC238423A08A70203010001";@b@ @b@ private static String privateKey = "30820277020100300D06092A864886F70D0101010500048202613082025D0201000281810088E387781D6B112B76D6353877AFA271B3F7B73EC149ADC984574F8B37F9BE7F390D7B22F1E36640912C88F6285B2878176D8108AB031CE6ECF21186F8AED9B2262DEC9CC1D0D83EB242A90BC2CEAAB168BB729F13438A75F842D6361F51B27BFFBAF3091EB18E9DDA773EA19DE994A424478BB1F7C0C705C7CDC238423A08A702030100010281803DFCB282ACE7A7EDC3B17A8628848B0DEC0DF797DE552BF23E107F7FAE8854402E28B1A30060161494E8D2D88D2BC266A74D3A0A1FCE980EE62B33CEA7DC1DCDC7BA3E024359C2DA5C4F1F60E22D7616710F093441E0B5355D739F900F4458B6AF0C2EDA987C794623719C6E9A3E62B9109C3DD67D6C1E5042F5283A1CAE0291024100DA4BCC2A65309A1EF16C347CDE559875DBC501DD07DFA99D75A5A7AEE7B1C0971C9950A6D7F38B10493B46C2F746197A4D2EBB407014D59EA925F444F168083F024100A08837D1C3BC1CB8E903B19F8072F629ED10295B382914D169ED069BDC7C422923CD9FE025A493C72652BBDF630F9C65763232822F57B80D7078B1F6F7242599024100B9386D205FC19053C6F6CFC64F84031BA580906731C21611D37BDE3E6ABB08B56EFFAB4E1597C09BEDF70CC06ABD20EB03C82DFBABDE11AF50C8326DB903535302403E64B34D544648E395AD59DC24908A1CC187068BEDC809CF5ADC45354EFCFCBA00B06AF333AE43C1A3A38461CE9EC2AAACC5D5DBC38AD47E64B88472F89B9401024100BD85C9BFE53C1757FB091C43EB265BA35B9D4EEBB0EF703472E3F7E3D3D94F727F90B84875D591EFB7E9438A6ADA5F49097904BCDB1F9F68B6E552399252F401";@b@@b@ private static String aesKey = "a6d6237e35a9eafb68c40463ae2a1d76";@b@ @b@ public static void main(String[] args) throws Exception {@b@ Map<String, String> map = new HashMap<String, String>();@b@ map.put("channel", "pa001");@b@ map.put("userName", "用户姓名");@b@ map.put("idNo", "230142000000000000");@b@ map.put("idType", "1");@b@ map.put("umCode", "G001");@b@ map.put("timestamp", String.valueOf(System.currentTimeMillis()));@b@ map.put("userId", "us001");@b@ map.put("returnUrl", "https://www.xwood.net");@b@ String ciphertext = AESDataCipherUtil.encrypt(JSONObject.toJSONString(map), aesKey);@b@ String sign = RSADataSignUtil.sign(ciphertext, privateKey);@b@ System.out.println(ciphertext);@b@ System.out.println(sign);@b@ @b@ boolean flag = RSADataSignUtil.verify(ciphertext, sign, publicKey);@b@ if (flag) {@b@ System.out.println("签名通过");@b@ String param = AESDataCipherUtil.decrypt(ciphertext, aesKey);@b@ System.out.println(param);@b@ JSONObject body = JSON.parseObject(param);@b@ @b@ System.out.println(body.getString("idNo"));@b@ }@b@ @b@ }@b@@b@ public static Map<String, String> genKey() throws Exception {@b@ Map<String, String> returnMap = new HashMap<String, String>();@b@ KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);@b@ SecureRandom random = new SecureRandom();@b@ keygen.initialize(1024, random);@b@ // 取得密钥对@b@ KeyPair kp = keygen.generateKeyPair();@b@ RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();@b@ String privateKeyString = bytesToHexStr(privateKey.getEncoded());@b@@b@ RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();@b@ String publicKeyString = bytesToHexStr(publicKey.getEncoded());@b@ returnMap.put("publicKey", publicKeyString);@b@ returnMap.put("privateKey", privateKeyString);@b@ @b@ System.out.println("keys-gen public_key:" + publicKeyString.toString());@b@ System.out.println("keys-gen private_key:" + privateKeyString.toString());@b@ @b@ return returnMap;@b@ }@b@@b@ public static RSAPublicKey getPublicKey(String publicKey) throws Exception {@b@ byte[] keyBytes = hexStrToBytes(publicKey);@b@ X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);@b@ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);@b@ return (RSAPublicKey) keyFactory.generatePublic(spec);@b@ }@b@@b@ public static RSAPrivateKey getPrivateKey(String privateKey) throws Exception {@b@ byte[] keyBytes = hexStrToBytes(privateKey);@b@ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);@b@ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);@b@ return (RSAPrivateKey) keyFactory.generatePrivate(spec);@b@ }@b@ @b@ public static String encrypt(Map<String, String> params, String publicKey) throws Exception {@b@ JSONObject object = new JSONObject();@b@ object.putAll(params);@b@ return encrypt(object.toString(), publicKey);@b@ }@b@@b@ public static String encrypt(String info, String publicKey) throws Exception {@b@ RSAPublicKey publickey = getPublicKey(publicKey);@b@ byte[] bytes = encrypt(info.getBytes("utf-8"), publickey);@b@ return bytesToHexStr(bytes);@b@ }@b@ @b@ private static byte[] encrypt(byte[] text, RSAPublicKey pubRSA) throws Exception {@b@ Cipher cipher = Cipher.getInstance("RSA");@b@ cipher.init(Cipher.ENCRYPT_MODE, pubRSA);@b@ byte[] dataReturn = new byte[0];@b@ for (int i = 0; i < text.length; i += 245) { @b@ byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(text, i, i + 245)); @b@ dataReturn = ArrayUtils.addAll(dataReturn, doFinal); @b@ } @b@ return dataReturn;@b@ }@b@ @b@ @b@ @b@ public static String decrypt(String sign, String privateKey) throws Exception {@b@ RSAPrivateKey privatekey = getPrivateKey(privateKey);@b@ byte[] bytes = decrypt((hexStrToBytes(sign)), privatekey);@b@ return new String(bytes, "utf-8");@b@ }@b@@b@ private static byte[] decrypt(byte[] src, RSAPrivateKey prK) throws Exception {@b@ Cipher cipher = Cipher.getInstance("RSA");@b@ cipher.init(Cipher.DECRYPT_MODE, prK);@b@ byte[] dataReturn = new byte[0];@b@ for (int i = 0; i < src.length; i += 256) { @b@ byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(src, i, i + 256)); @b@ dataReturn = ArrayUtils.addAll(dataReturn, doFinal); @b@ } @b@ return dataReturn;@b@ }@b@@b@ /**@b@ * Transform the specified byte into a Hex String form.@b@ */@b@ private static final String bytesToHexStr(byte[] bcd) {@b@ StringBuffer s = new StringBuffer(bcd.length * 2);@b@ for (int i = 0; i < bcd.length; i++) {@b@ s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);@b@ s.append(bcdLookup[bcd[i] & 0x0f]);@b@ }@b@ return s.toString();@b@ }@b@@b@ /**@b@ * Transform the specified Hex String into a byte array.@b@ */@b@ private static final byte[] hexStrToBytes(String s) {@b@ byte[] bytes;@b@ bytes = new byte[s.length() / 2];@b@ for (int i = 0; i < bytes.length; i++) {@b@ bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);@b@ }@b@ return bytes;@b@ }@b@@b@}
控制台输出结果如下
3d0cd6082bd25ccabaf2132dbd72e4f3df8cab4eb48229cfd3932346ff9d38114719023d82d1f844d4ccfc7c881ab94d326aef368b0c6b573d9b47aa0ab8e186b44033e780965865a71e7948edb432bd8cb9afbcbb38663200fd93b251d0dffad4acb9b9c24a10674c8ae266ebe02cccd21b9a8b103a1deac541f6c63e9b0e0032d30c60c8089dc44b60ffe22c2f4db97e28c2286c5e18fc89d6f687ce0129b17c22c934b3dc05d0e2e20c1c0c3c0d4c6a3a86efa7ce3208b56abcb411b36ba1@b@841636d5b300a071aa5cf77f85f0e431d119f73bff7bc103aa559e54fb3e59b1ab2b513fd93d8d9e4ecd9145c4547d01a1972d1da0594161b291ef816cdef3b3d2c3fe440b1445c250c0abe9c1c009c17af25444625e3a1e5955b3b6bedeeb088f6d853d4d7404a78ce14f365c95e41a79b6411e6346c090ba5a9b07d6eeaa9c@b@签名通过@b@{"returnUrl":"https://www.xwood.net","timestamp":"1498669911012","idNo":"230142000000000000","idType":"1","umCode":"G001","userId":"us001","userName":"用户姓名","channel":"pa001"}@b@230142000000000000