首页

基于RSA非对称公私钥对结合AES数据加解密方式实现加解签验证和数据的加解密算法代码示例

标签:非对称,公钥,密钥对,安全,加签,解签,rsa,aes,KeyGenerator,SecretKeySpec,PKCS8EncodedKeySpec,X509EncodedKeySpec     发布时间:2017-06-28   

一、前言

基于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