package xin.glue.cargocnHttpClient; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileReader; import java.io.IOException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; 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.Cipher; public class RSAUtils { /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** *

* 用私钥对信息生成数字签名 *

* * @param data * 已加密数据 * @param privateKey * 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64.encode(signature.sign()); } /** */ /** *

* 校验数字签名 *

* * @param data * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @param sign * 数字签名 * * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64.decode(sign)); } /** */ /** *

* 私钥解密 *

* * @param encryptedData * 已加密数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher .doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** */ /** *

* 公钥解密 *

* * @param encryptedData * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = Base64.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher .doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** */ /** *

* 公钥加密 *

* @param data 源数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { byte[] keyBytes = Base64.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** */ /** *

* 私钥加密 *

* @param data 源数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * 从文件中输入流中加载公钥 * @param in 公钥输入流 * @throws Exception 加载公钥时产生的异常 */ public static String loadPublicKeyByFile(String path) throws Exception { try { path = java.net.URLDecoder.decode(path,"utf-8"); BufferedReader br = new BufferedReader(new FileReader(path)); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { sb.append(readLine); } br.close(); return getPem("PUBLIC KEY", sb.toString()); } catch (IOException e) { throw new Exception("公钥数据流读取错误"); } catch (NullPointerException e) { throw new Exception("公钥输入流为空"); } } /** * 从文件中输入流中加载公钥 * @param path = "PUB" 为公钥,"PRI"为私钥 公钥输入流 * @throws Exception 加载公钥时产生的异常 */ public static String loadKeyStr(String path) throws Exception { /* -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vWJpbaQloLmi1nf0v90Sk1TZ WvPEl4aXuSTGbnw6FTaF/Mf4Gcvj59a+j/dE/ZsAo8WRh7g3qviBZ78tdsJn+Nvi 9H9KZhAuMSFbob82mMD2aiASnbEl3uE4hdlYoj59nWiX6W7APnMOuUyZ2u8z5AwI wt1/4+9XAvZ3cNOA2wIDAQAB -----END PUBLIC KEY----- */ /* -----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALGn68OHTm3Ewe08 nYvyQUI7naTf9af3FEe4yikFlgsPTAKDXX1hrGfS1Amk2wVBiAjEfmlghqi557JB obeiTlXGMUF0ATLoXWKMdKMFZK3IcG/8hauQhW2l5RUiSN+4Qf38XP/yT3eoLvxA 82+AzFrpuF4pR6UvjFo4eY7qlv2FAgMBAAECgYAvGCGSkqLCzH7QAdqNx6lvAli2 5Tu8y+3PWXgVycpNoj93BxXYb/UBDM1yxQXebdG+6T/NdW4c+jMmeOmCwX7cItgH UgLmfEqF3PE/U7oIunNh2Q3wbqkljnh9Df7NTapu/6eOn4vhFdQRYJalM7FM5oZc 9UETRESXoUqgKc/KIQJBAOBu1zQu0d5Sg+CIVZ6YWbm1NvdvtqPPyGjXBItIotRT 128LLnEnd2OV5D1+l+uR+xPkozs5O/puOifN5w+9gu0CQQDKpMeN0Ed/8O7b6jxD uOo8FepXLjCBlq7WQmXIjv22W3LlOTS7Xmy5wf8dlQcORdg2U3cX4AueAdHhVhg4 r5n5AkALymbt6+PErUsWWbM90L0t/3Iyz6ClvH3H3Dv14UwEoZ74y3qWIT+pcK97 95Gdo56wLdvRebFH99CAVNXlwswFAkAXtCKrkftrGdG247Vc7ppnoOCihgKihe+5 nFavmRpQZG4SJhjm+eqZ5/lhinci0kSyRh0eK9TwDKJyS1HV/6RxAkEA3mZizaTs 9ppt9lXYhLudK6e1ryqFOdDg2wkWA5oUYZ0IDdM7z9jEkR0ya1keUIkTJCkegLrI RSSPXymOqTGfaA== -----END PRIVATE KEY----- */ StringBuilder sb = new StringBuilder(); if("PUB".equals(path)) { sb.append("-----BEGIN PUBLIC KEY-----"); sb.append("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vWJpbaQloLmi1nf0v90Sk1TZ"); sb.append("WvPEl4aXuSTGbnw6FTaF/Mf4Gcvj59a+j/dE/ZsAo8WRh7g3qviBZ78tdsJn+Nvi"); sb.append("9H9KZhAuMSFbob82mMD2aiASnbEl3uE4hdlYoj59nWiX6W7APnMOuUyZ2u8z5AwI"); sb.append("wt1/4+9XAvZ3cNOA2wIDAQAB"); sb.append("-----END PUBLIC KEY-----"); return getPem("PUBLIC KEY", sb.toString()); } else { sb.append("-----BEGIN PRIVATE KEY-----"); sb.append("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALGn68OHTm3Ewe08"); sb.append("nYvyQUI7naTf9af3FEe4yikFlgsPTAKDXX1hrGfS1Amk2wVBiAjEfmlghqi557JB"); sb.append("obeiTlXGMUF0ATLoXWKMdKMFZK3IcG/8hauQhW2l5RUiSN+4Qf38XP/yT3eoLvxA"); sb.append("82+AzFrpuF4pR6UvjFo4eY7qlv2FAgMBAAECgYAvGCGSkqLCzH7QAdqNx6lvAli2"); sb.append("5Tu8y+3PWXgVycpNoj93BxXYb/UBDM1yxQXebdG+6T/NdW4c+jMmeOmCwX7cItgH"); sb.append("UgLmfEqF3PE/U7oIunNh2Q3wbqkljnh9Df7NTapu/6eOn4vhFdQRYJalM7FM5oZc"); sb.append("9UETRESXoUqgKc/KIQJBAOBu1zQu0d5Sg+CIVZ6YWbm1NvdvtqPPyGjXBItIotRT"); sb.append("128LLnEnd2OV5D1+l+uR+xPkozs5O/puOifN5w+9gu0CQQDKpMeN0Ed/8O7b6jxD"); sb.append("uOo8FepXLjCBlq7WQmXIjv22W3LlOTS7Xmy5wf8dlQcORdg2U3cX4AueAdHhVhg4"); sb.append("r5n5AkALymbt6+PErUsWWbM90L0t/3Iyz6ClvH3H3Dv14UwEoZ74y3qWIT+pcK97"); sb.append("95Gdo56wLdvRebFH99CAVNXlwswFAkAXtCKrkftrGdG247Vc7ppnoOCihgKihe+5"); sb.append("nFavmRpQZG4SJhjm+eqZ5/lhinci0kSyRh0eK9TwDKJyS1HV/6RxAkEA3mZizaTs"); sb.append("9ppt9lXYhLudK6e1ryqFOdDg2wkWA5oUYZ0IDdM7z9jEkR0ya1keUIkTJCkegLrI"); sb.append("RSSPXymOqTGfaA=="); sb.append("-----END PRIVATE KEY----- "); return getPem("PRIVATE KEY", sb.toString()); } } /** * 从字符串中加载公钥 * * @param publicKeyStr * 公钥数据字符串 * @throws Exception * 加载公钥时产生的异常 */ public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr) throws Exception { try { byte[] buffer = Base64.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) { e.printStackTrace(); throw new Exception("公钥数据为空"); } } private static String getPem(String type, String keyStr) { String header = "-----BEGIN " + type + "-----\\n"; String footer = "-----END " + type + "-----"; int start = keyStr.indexOf(header) + header.length() - 1; int end = keyStr.indexOf(footer, start); return keyStr.substring(start, end); } /** * 从文件中加载私钥 * * @param keyFileName * 私钥文件名 * @return 是否成功 * @throws Exception */ public static String loadPrivateKeyByFile(String path) throws Exception { try { path = java.net.URLDecoder.decode(path,"utf-8"); BufferedReader br = new BufferedReader(new FileReader(path)); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { sb.append(readLine); } br.close(); return getPem("PRIVATE KEY", 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 = Base64.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("私钥数据为空"); } } }