39032ecc71f047a9caf3703ce10a8c94dc09d9d1.svn-base 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. package xin.glue.cargocnHttpClient;
  2. import java.io.BufferedReader;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.FileReader;
  5. import java.io.IOException;
  6. import java.security.Key;
  7. import java.security.KeyFactory;
  8. import java.security.NoSuchAlgorithmException;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.Signature;
  12. import java.security.interfaces.RSAPrivateKey;
  13. import java.security.interfaces.RSAPublicKey;
  14. import java.security.spec.InvalidKeySpecException;
  15. import java.security.spec.PKCS8EncodedKeySpec;
  16. import java.security.spec.X509EncodedKeySpec;
  17. import javax.crypto.Cipher;
  18. public class RSAUtils {
  19. /**
  20. * 加密算法RSA
  21. */
  22. public static final String KEY_ALGORITHM = "RSA";
  23. /**
  24. * 签名算法
  25. */
  26. public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
  27. /**
  28. * RSA最大加密明文大小
  29. */
  30. private static final int MAX_ENCRYPT_BLOCK = 117;
  31. /**
  32. * RSA最大解密密文大小
  33. */
  34. private static final int MAX_DECRYPT_BLOCK = 128;
  35. /**
  36. * <p>
  37. * 用私钥对信息生成数字签名
  38. * </p>
  39. *
  40. * @param data
  41. * 已加密数据
  42. * @param privateKey
  43. * 私钥(BASE64编码)
  44. *
  45. * @return
  46. * @throws Exception
  47. */
  48. public static String sign(byte[] data, String privateKey) throws Exception {
  49. byte[] keyBytes = Base64.decode(privateKey);
  50. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  51. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  52. PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  53. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  54. signature.initSign(privateK);
  55. signature.update(data);
  56. return Base64.encode(signature.sign());
  57. }
  58. /** */
  59. /**
  60. * <p>
  61. * 校验数字签名
  62. * </p>
  63. *
  64. * @param data
  65. * 已加密数据
  66. * @param publicKey
  67. * 公钥(BASE64编码)
  68. * @param sign
  69. * 数字签名
  70. *
  71. * @return
  72. * @throws Exception
  73. *
  74. */
  75. public static boolean verify(byte[] data, String publicKey, String sign)
  76. throws Exception {
  77. byte[] keyBytes = Base64.decode(publicKey);
  78. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  79. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  80. PublicKey publicK = keyFactory.generatePublic(keySpec);
  81. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  82. signature.initVerify(publicK);
  83. signature.update(data);
  84. return signature.verify(Base64.decode(sign));
  85. }
  86. /** */
  87. /**
  88. * <P>
  89. * 私钥解密
  90. * </p>
  91. *
  92. * @param encryptedData
  93. * 已加密数据
  94. * @param privateKey
  95. * 私钥(BASE64编码)
  96. * @return
  97. * @throws Exception
  98. */
  99. public static byte[] decryptByPrivateKey(byte[] encryptedData,
  100. String privateKey) throws Exception {
  101. byte[] keyBytes = Base64.decode(privateKey);
  102. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  103. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  104. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  105. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  106. cipher.init(Cipher.DECRYPT_MODE, privateK);
  107. int inputLen = encryptedData.length;
  108. ByteArrayOutputStream out = new ByteArrayOutputStream();
  109. int offSet = 0;
  110. byte[] cache;
  111. int i = 0;
  112. // 对数据分段解密
  113. while (inputLen - offSet > 0) {
  114. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  115. cache = cipher
  116. .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
  117. } else {
  118. cache = cipher
  119. .doFinal(encryptedData, offSet, inputLen - offSet);
  120. }
  121. out.write(cache, 0, cache.length);
  122. i++;
  123. offSet = i * MAX_DECRYPT_BLOCK;
  124. }
  125. byte[] decryptedData = out.toByteArray();
  126. out.close();
  127. return decryptedData;
  128. }
  129. /** */
  130. /**
  131. * <p>
  132. * 公钥解密
  133. * </p>
  134. *
  135. * @param encryptedData
  136. * 已加密数据
  137. * @param publicKey
  138. * 公钥(BASE64编码)
  139. * @return
  140. * @throws Exception
  141. */
  142. public static byte[] decryptByPublicKey(byte[] encryptedData,
  143. String publicKey) throws Exception {
  144. byte[] keyBytes = Base64.decode(publicKey);
  145. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  146. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  147. Key publicK = keyFactory.generatePublic(x509KeySpec);
  148. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  149. cipher.init(Cipher.DECRYPT_MODE, publicK);
  150. int inputLen = encryptedData.length;
  151. ByteArrayOutputStream out = new ByteArrayOutputStream();
  152. int offSet = 0;
  153. byte[] cache;
  154. int i = 0;
  155. // 对数据分段解密
  156. while (inputLen - offSet > 0) {
  157. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  158. cache = cipher
  159. .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
  160. } else {
  161. cache = cipher
  162. .doFinal(encryptedData, offSet, inputLen - offSet);
  163. }
  164. out.write(cache, 0, cache.length);
  165. i++;
  166. offSet = i * MAX_DECRYPT_BLOCK;
  167. }
  168. byte[] decryptedData = out.toByteArray();
  169. out.close();
  170. return decryptedData;
  171. }
  172. /** */
  173. /**
  174. * <p>
  175. * 公钥加密
  176. * </p>
  177. * @param data 源数据
  178. * @param publicKey 公钥(BASE64编码)
  179. * @return
  180. * @throws Exception
  181. */
  182. public static byte[] encryptByPublicKey(byte[] data, String publicKey)
  183. throws Exception {
  184. byte[] keyBytes = Base64.decode(publicKey);
  185. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  186. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  187. Key publicK = keyFactory.generatePublic(x509KeySpec);
  188. // 对数据加密
  189. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  190. cipher.init(Cipher.ENCRYPT_MODE, publicK);
  191. int inputLen = data.length;
  192. ByteArrayOutputStream out = new ByteArrayOutputStream();
  193. int offSet = 0;
  194. byte[] cache;
  195. int i = 0;
  196. // 对数据分段加密
  197. while (inputLen - offSet > 0) {
  198. if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  199. cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  200. } else {
  201. cache = cipher.doFinal(data, offSet, inputLen - offSet);
  202. }
  203. out.write(cache, 0, cache.length);
  204. i++;
  205. offSet = i * MAX_ENCRYPT_BLOCK;
  206. }
  207. byte[] encryptedData = out.toByteArray();
  208. out.close();
  209. return encryptedData;
  210. }
  211. /** */
  212. /**
  213. * <p>
  214. * 私钥加密
  215. * </p>
  216. * @param data 源数据
  217. * @param privateKey 私钥(BASE64编码)
  218. * @return
  219. * @throws Exception
  220. */
  221. public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
  222. throws Exception {
  223. byte[] keyBytes = Base64.decode(privateKey);
  224. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  225. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  226. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  227. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  228. cipher.init(Cipher.ENCRYPT_MODE, privateK);
  229. int inputLen = data.length;
  230. ByteArrayOutputStream out = new ByteArrayOutputStream();
  231. int offSet = 0;
  232. byte[] cache;
  233. int i = 0;
  234. // 对数据分段加密
  235. while (inputLen - offSet > 0) {
  236. if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  237. cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  238. } else {
  239. cache = cipher.doFinal(data, offSet, inputLen - offSet);
  240. }
  241. out.write(cache, 0, cache.length);
  242. i++;
  243. offSet = i * MAX_ENCRYPT_BLOCK;
  244. }
  245. byte[] encryptedData = out.toByteArray();
  246. out.close();
  247. return encryptedData;
  248. }
  249. /**
  250. * 从文件中输入流中加载公钥
  251. * @param in 公钥输入流
  252. * @throws Exception 加载公钥时产生的异常
  253. */
  254. public static String loadPublicKeyByFile(String path) throws Exception {
  255. try {
  256. path = java.net.URLDecoder.decode(path,"utf-8");
  257. BufferedReader br = new BufferedReader(new FileReader(path));
  258. String readLine = null;
  259. StringBuilder sb = new StringBuilder();
  260. while ((readLine = br.readLine()) != null) {
  261. sb.append(readLine);
  262. }
  263. br.close();
  264. return getPem("PUBLIC KEY", sb.toString());
  265. } catch (IOException e) {
  266. throw new Exception("公钥数据流读取错误");
  267. } catch (NullPointerException e) {
  268. throw new Exception("公钥输入流为空");
  269. }
  270. }
  271. /**
  272. * 从文件中输入流中加载公钥
  273. * @param path = "PUB" 为公钥,"PRI"为私钥 公钥输入流
  274. * @throws Exception 加载公钥时产生的异常
  275. */
  276. public static String loadKeyStr(String path) throws Exception {
  277. /*
  278. -----BEGIN PUBLIC KEY-----
  279. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vWJpbaQloLmi1nf0v90Sk1TZ
  280. WvPEl4aXuSTGbnw6FTaF/Mf4Gcvj59a+j/dE/ZsAo8WRh7g3qviBZ78tdsJn+Nvi
  281. 9H9KZhAuMSFbob82mMD2aiASnbEl3uE4hdlYoj59nWiX6W7APnMOuUyZ2u8z5AwI
  282. wt1/4+9XAvZ3cNOA2wIDAQAB
  283. -----END PUBLIC KEY-----
  284. */
  285. /*
  286. -----BEGIN PRIVATE KEY-----
  287. MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALGn68OHTm3Ewe08
  288. nYvyQUI7naTf9af3FEe4yikFlgsPTAKDXX1hrGfS1Amk2wVBiAjEfmlghqi557JB
  289. obeiTlXGMUF0ATLoXWKMdKMFZK3IcG/8hauQhW2l5RUiSN+4Qf38XP/yT3eoLvxA
  290. 82+AzFrpuF4pR6UvjFo4eY7qlv2FAgMBAAECgYAvGCGSkqLCzH7QAdqNx6lvAli2
  291. 5Tu8y+3PWXgVycpNoj93BxXYb/UBDM1yxQXebdG+6T/NdW4c+jMmeOmCwX7cItgH
  292. UgLmfEqF3PE/U7oIunNh2Q3wbqkljnh9Df7NTapu/6eOn4vhFdQRYJalM7FM5oZc
  293. 9UETRESXoUqgKc/KIQJBAOBu1zQu0d5Sg+CIVZ6YWbm1NvdvtqPPyGjXBItIotRT
  294. 128LLnEnd2OV5D1+l+uR+xPkozs5O/puOifN5w+9gu0CQQDKpMeN0Ed/8O7b6jxD
  295. uOo8FepXLjCBlq7WQmXIjv22W3LlOTS7Xmy5wf8dlQcORdg2U3cX4AueAdHhVhg4
  296. r5n5AkALymbt6+PErUsWWbM90L0t/3Iyz6ClvH3H3Dv14UwEoZ74y3qWIT+pcK97
  297. 95Gdo56wLdvRebFH99CAVNXlwswFAkAXtCKrkftrGdG247Vc7ppnoOCihgKihe+5
  298. nFavmRpQZG4SJhjm+eqZ5/lhinci0kSyRh0eK9TwDKJyS1HV/6RxAkEA3mZizaTs
  299. 9ppt9lXYhLudK6e1ryqFOdDg2wkWA5oUYZ0IDdM7z9jEkR0ya1keUIkTJCkegLrI
  300. RSSPXymOqTGfaA==
  301. -----END PRIVATE KEY-----
  302. */
  303. StringBuilder sb = new StringBuilder();
  304. if("PUB".equals(path)) {
  305. sb.append("-----BEGIN PUBLIC KEY-----");
  306. sb.append("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vWJpbaQloLmi1nf0v90Sk1TZ");
  307. sb.append("WvPEl4aXuSTGbnw6FTaF/Mf4Gcvj59a+j/dE/ZsAo8WRh7g3qviBZ78tdsJn+Nvi");
  308. sb.append("9H9KZhAuMSFbob82mMD2aiASnbEl3uE4hdlYoj59nWiX6W7APnMOuUyZ2u8z5AwI");
  309. sb.append("wt1/4+9XAvZ3cNOA2wIDAQAB");
  310. sb.append("-----END PUBLIC KEY-----");
  311. return getPem("PUBLIC KEY", sb.toString());
  312. } else {
  313. sb.append("-----BEGIN PRIVATE KEY-----");
  314. sb.append("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALGn68OHTm3Ewe08");
  315. sb.append("nYvyQUI7naTf9af3FEe4yikFlgsPTAKDXX1hrGfS1Amk2wVBiAjEfmlghqi557JB");
  316. sb.append("obeiTlXGMUF0ATLoXWKMdKMFZK3IcG/8hauQhW2l5RUiSN+4Qf38XP/yT3eoLvxA");
  317. sb.append("82+AzFrpuF4pR6UvjFo4eY7qlv2FAgMBAAECgYAvGCGSkqLCzH7QAdqNx6lvAli2");
  318. sb.append("5Tu8y+3PWXgVycpNoj93BxXYb/UBDM1yxQXebdG+6T/NdW4c+jMmeOmCwX7cItgH");
  319. sb.append("UgLmfEqF3PE/U7oIunNh2Q3wbqkljnh9Df7NTapu/6eOn4vhFdQRYJalM7FM5oZc");
  320. sb.append("9UETRESXoUqgKc/KIQJBAOBu1zQu0d5Sg+CIVZ6YWbm1NvdvtqPPyGjXBItIotRT");
  321. sb.append("128LLnEnd2OV5D1+l+uR+xPkozs5O/puOifN5w+9gu0CQQDKpMeN0Ed/8O7b6jxD");
  322. sb.append("uOo8FepXLjCBlq7WQmXIjv22W3LlOTS7Xmy5wf8dlQcORdg2U3cX4AueAdHhVhg4");
  323. sb.append("r5n5AkALymbt6+PErUsWWbM90L0t/3Iyz6ClvH3H3Dv14UwEoZ74y3qWIT+pcK97");
  324. sb.append("95Gdo56wLdvRebFH99CAVNXlwswFAkAXtCKrkftrGdG247Vc7ppnoOCihgKihe+5");
  325. sb.append("nFavmRpQZG4SJhjm+eqZ5/lhinci0kSyRh0eK9TwDKJyS1HV/6RxAkEA3mZizaTs");
  326. sb.append("9ppt9lXYhLudK6e1ryqFOdDg2wkWA5oUYZ0IDdM7z9jEkR0ya1keUIkTJCkegLrI");
  327. sb.append("RSSPXymOqTGfaA==");
  328. sb.append("-----END PRIVATE KEY----- ");
  329. return getPem("PRIVATE KEY", sb.toString());
  330. }
  331. }
  332. /**
  333. * 从字符串中加载公钥
  334. *
  335. * @param publicKeyStr
  336. * 公钥数据字符串
  337. * @throws Exception
  338. * 加载公钥时产生的异常
  339. */
  340. public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
  341. throws Exception {
  342. try {
  343. byte[] buffer = Base64.decode(publicKeyStr);
  344. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  345. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
  346. return (RSAPublicKey) keyFactory.generatePublic(keySpec);
  347. } catch (NoSuchAlgorithmException e) {
  348. throw new Exception("无此算法");
  349. } catch (InvalidKeySpecException e) {
  350. throw new Exception("公钥非法");
  351. } catch (NullPointerException e) {
  352. e.printStackTrace();
  353. throw new Exception("公钥数据为空");
  354. }
  355. }
  356. private static String getPem(String type, String keyStr) {
  357. String header = "-----BEGIN " + type + "-----\\n";
  358. String footer = "-----END " + type + "-----";
  359. int start = keyStr.indexOf(header) + header.length() - 1;
  360. int end = keyStr.indexOf(footer, start);
  361. return keyStr.substring(start, end);
  362. }
  363. /**
  364. * 从文件中加载私钥
  365. *
  366. * @param keyFileName
  367. * 私钥文件名
  368. * @return 是否成功
  369. * @throws Exception
  370. */
  371. public static String loadPrivateKeyByFile(String path) throws Exception {
  372. try {
  373. path = java.net.URLDecoder.decode(path,"utf-8");
  374. BufferedReader br = new BufferedReader(new FileReader(path));
  375. String readLine = null;
  376. StringBuilder sb = new StringBuilder();
  377. while ((readLine = br.readLine()) != null) {
  378. sb.append(readLine);
  379. }
  380. br.close();
  381. return getPem("PRIVATE KEY", sb.toString());
  382. } catch (IOException e) {
  383. throw new Exception("私钥数据读取错误");
  384. } catch (NullPointerException e) {
  385. throw new Exception("私钥输入流为空");
  386. }
  387. }
  388. public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
  389. throws Exception {
  390. try {
  391. byte[] buffer = Base64.decode(privateKeyStr);
  392. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
  393. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  394. return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
  395. } catch (NoSuchAlgorithmException e) {
  396. throw new Exception("无此算法");
  397. } catch (InvalidKeySpecException e) {
  398. throw new Exception("私钥非法");
  399. } catch (NullPointerException e) {
  400. throw new Exception("私钥数据为空");
  401. }
  402. }
  403. }