加密证书和RSA加密解密

╰+哭是因爲堅強的太久メ 2022-08-20 12:07 220阅读 0赞

最近一直在做与第三方的支付业务,因为数据涉及到了钱,所以交互的数据保密性非常的重要!主要应用的是RSA加密机制,整理一下共享给大家!
1、生成加密证书

1)产生证书的工具:openssl;openssl的官方推荐网站下载:http://slproweb.com/products/Win32OpenSSL.html

2)配置文件:我下载的是win-64位轻量版的:Win64OpenSSL-1_0_2f.exe,下载之后解压到C盘(我刚开始是解压到其他盘的,但是出现错误:can’t open config file: /usr/local/ssl/openssl.cnf,有人说配置环境变量:set OPENSSL_CONF=..\conf\openssl.cnf ;我是了不好使,大家查出来是什么问题可以告诉我一下,哈哈)在C盘根目录依次建立usr/local/ssl/openssl.cnf文件后,下载地址:http://download.csdn.net/detail/qq_32347977/9396321

3)生成采用des3算法保护的私钥:
OpenSSL> genrsa -des3 -out private-rsa.key 1024
命令执行过程中的提示信息Enter pass phrase 的含义是输入用来保护私钥文件的密码(不要超过6位),我的是123456。

4) 生成公钥证书:
OpenSSL> req -new -x509 -key private-rsa.key -days 750 -out public-rsa.cer
该过程除了最开始时需要输入私钥文件的保护密码之外,其他需要的输入均可直接回车忽略,不影响正常使用。

5)生成PKCS12 格式Keystore:
OpenSSL> pkcs12 -export -name test-alias -in public-rsa.cer -inkey private-rsa.key -out user-rsa.pfx
这里写图片描述
这样就ok了。

AES工具类:

  1. package com.alex.util;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.KeyGenerator;
  4. import javax.crypto.spec.SecretKeySpec;
  5. import java.io.UnsupportedEncodingException;
  6. import java.security.Key;
  7. import java.security.NoSuchAlgorithmException;
  8. import java.security.SecureRandom;
  9. public class AES {
  10. public static final String CHAR_ENCODING = "UTF-8";
  11. public static final String AES_ALGORITHM = "AES/ECB/PKCS5Padding";
  12. /** * 加密 * * @param / data * 待加密密内容 * @param /key * 加密密钥 * @return */
  13. public static byte[] encrypt(byte[] data, byte[] key) {
  14. if(key.length!=16){
  15. throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
  16. }
  17. try {
  18. SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
  19. byte[] enCodeFormat = secretKey.getEncoded();
  20. SecretKeySpec seckey = new SecretKeySpec(enCodeFormat,"AES");
  21. Cipher cipher = Cipher.getInstance(AES_ALGORITHM);// 创建密码器
  22. cipher.init(Cipher.ENCRYPT_MODE, seckey);// 初始化
  23. byte[] result = cipher.doFinal(data);
  24. return result; // 加密
  25. } catch (Exception e){
  26. throw new RuntimeException("encrypt fail!", e);
  27. }
  28. }
  29. /** * 解密 * * @param / content * 待解密内容 * @param /password * 解密密钥 * @return */
  30. public static byte[] decrypt(byte[] data, byte[] key) {
  31. if(key.length!=16){
  32. throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
  33. }
  34. try {
  35. SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
  36. byte[] enCodeFormat = secretKey.getEncoded();
  37. SecretKeySpec seckey = new SecretKeySpec(enCodeFormat, "AES");
  38. Cipher cipher = Cipher.getInstance(AES_ALGORITHM);// 创建密码器
  39. cipher.init(Cipher.DECRYPT_MODE, seckey);// 初始化
  40. byte[] result = cipher.doFinal(data);
  41. return result; // 加密
  42. } catch (Exception e){
  43. throw new RuntimeException("decrypt fail!", e);
  44. }
  45. }
  46. public static String encryptToBase64(String data, String key){
  47. try {
  48. byte[] valueByte = encrypt(data.getBytes(CHAR_ENCODING), key.getBytes(CHAR_ENCODING));
  49. return new String(Base64.encode(valueByte));
  50. } catch (UnsupportedEncodingException e) {
  51. throw new RuntimeException("encrypt fail!", e);
  52. }
  53. }
  54. public static String decryptFromBase64(String data, String key){
  55. try {
  56. byte[] originalData = Base64.decode(data.getBytes());
  57. byte[] valueByte = decrypt(originalData, key.getBytes(CHAR_ENCODING));
  58. return new String(valueByte, CHAR_ENCODING);
  59. } catch (UnsupportedEncodingException e) {
  60. throw new RuntimeException("decrypt fail!", e);
  61. }
  62. }
  63. public static String encryptWithKeyBase64(String data, String key){
  64. try {
  65. byte[] valueByte = encrypt(data.getBytes(CHAR_ENCODING), Base64.decode(key.getBytes()));
  66. return new String(Base64.encode(valueByte));
  67. } catch (UnsupportedEncodingException e) {
  68. throw new RuntimeException("encrypt fail!", e);
  69. }
  70. }
  71. public static String decryptWithKeyBase64(String data, String key){
  72. try {
  73. byte[] originalData = Base64.decode(data.getBytes());
  74. byte[] valueByte = decrypt(originalData, Base64.decode(key.getBytes()));
  75. return new String(valueByte, CHAR_ENCODING);
  76. } catch (UnsupportedEncodingException e) {
  77. throw new RuntimeException("decrypt fail!", e);
  78. }
  79. }
  80. public static byte[] genarateRandomKey(){
  81. KeyGenerator keygen = null;
  82. try {
  83. keygen = KeyGenerator.getInstance(AES_ALGORITHM);
  84. } catch (NoSuchAlgorithmException e) {
  85. throw new RuntimeException(" genarateRandomKey fail!", e);
  86. }
  87. SecureRandom random = new SecureRandom();
  88. keygen.init(random);
  89. Key key = keygen.generateKey();
  90. return key.getEncoded();
  91. }
  92. public static String genarateRandomKeyWithBase64(){
  93. return new String(Base64.encode(genarateRandomKey()));
  94. }
  95. }

Base64工具类:

  1. package com.alex.util;
  2. import java.io.UnsupportedEncodingException;
  3. public class Base64 {
  4. /** * Chunk size per RFC 2045 section 6.8. * * <p>The {@value} character limit does not count the trailing CRLF, but counts * all other characters, including any equal signs.</p> * * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a> */
  5. static final int CHUNK_SIZE = 76;
  6. /** * Chunk separator per RFC 2045 section 2.1. * * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a> */
  7. static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
  8. /** * The base length. */
  9. static final int BASELENGTH = 255;
  10. /** * Lookup length. */
  11. static final int LOOKUPLENGTH = 64;
  12. /** * Used to calculate the number of bits in a byte. */
  13. static final int EIGHTBIT = 8;
  14. /** * Used when encoding something which has fewer than 24 bits. */
  15. static final int SIXTEENBIT = 16;
  16. /** * Used to determine how many bits data contains. */
  17. static final int TWENTYFOURBITGROUP = 24;
  18. /** * Used to get the number of Quadruples. */
  19. static final int FOURBYTE = 4;
  20. /** * Used to test the sign of a byte. */
  21. static final int SIGN = -128;
  22. /** * Byte used to pad output. */
  23. static final byte PAD = (byte) '=';
  24. // Create arrays to hold the base64 characters and a
  25. // lookup for base64 chars
  26. private static byte[] base64Alphabet = new byte[BASELENGTH];
  27. private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
  28. // Populating the lookup and character arrays
  29. static {
  30. for (int i = 0; i < BASELENGTH; i++) {
  31. base64Alphabet[i] = (byte) -1;
  32. }
  33. for (int i = 'Z'; i >= 'A'; i--) {
  34. base64Alphabet[i] = (byte) (i - 'A');
  35. }
  36. for (int i = 'z'; i >= 'a'; i--) {
  37. base64Alphabet[i] = (byte) (i - 'a' + 26);
  38. }
  39. for (int i = '9'; i >= '0'; i--) {
  40. base64Alphabet[i] = (byte) (i - '0' + 52);
  41. }
  42. base64Alphabet['+'] = 62;
  43. base64Alphabet['/'] = 63;
  44. for (int i = 0; i <= 25; i++) {
  45. lookUpBase64Alphabet[i] = (byte) ('A' + i);
  46. }
  47. for (int i = 26, j = 0; i <= 51; i++, j++) {
  48. lookUpBase64Alphabet[i] = (byte) ('a' + j);
  49. }
  50. for (int i = 52, j = 0; i <= 61; i++, j++) {
  51. lookUpBase64Alphabet[i] = (byte) ('0' + j);
  52. }
  53. lookUpBase64Alphabet[62] = (byte) '+';
  54. lookUpBase64Alphabet[63] = (byte) '/';
  55. }
  56. private static boolean isBase64(byte octect) {
  57. if (octect == PAD) {
  58. return true;
  59. } else if (base64Alphabet[octect] == -1) {
  60. return false;
  61. } else {
  62. return true;
  63. }
  64. }
  65. /** * Tests a given byte array to see if it contains * only valid characters within the Base64 alphabet. * * @param arrayOctect byte array to test * @return true if all bytes are valid characters in the Base64 * alphabet or if the byte array is empty; false, otherwise */
  66. public static boolean isArrayByteBase64(byte[] arrayOctect) {
  67. arrayOctect = discardWhitespace(arrayOctect);
  68. int length = arrayOctect.length;
  69. if (length == 0) {
  70. // shouldn't a 0 length array be valid base64 data?
  71. // return false;
  72. return true;
  73. }
  74. for (int i = 0; i < length; i++) {
  75. if (!isBase64(arrayOctect[i])) {
  76. return false;
  77. }
  78. }
  79. return true;
  80. }
  81. /** * Encodes binary data using the base64 algorithm but * does not chunk the output. * * @param binaryData binary data to encode * @return Base64 characters */
  82. public static byte[] encodeBase64(byte[] binaryData) {
  83. return encodeBase64(binaryData, false);
  84. }
  85. /** * Encodes binary data using the base64 algorithm and chunks * the encoded output into 76 character blocks * * @param binaryData binary data to encode * @return Base64 characters chunked in 76 character blocks */
  86. public static byte[] encodeBase64Chunked(byte[] binaryData) {
  87. return encodeBase64(binaryData, true);
  88. }
  89. /** * Decodes a byte[] containing containing * characters in the Base64 alphabet. * * @param pArray A byte array containing Base64 character data * @return a byte array containing binary data */
  90. public static byte[] decode(byte[] pArray) {
  91. return decodeBase64(pArray);
  92. }
  93. /** * Encodes binary data using the base64 algorithm, optionally * chunking the output into 76 character blocks. * * @param binaryData Array containing binary data to encode. * @param isChunked if isChunked is true this encoder will chunk * the base64 output into 76 character blocks * @return Base64-encoded data. */
  94. public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
  95. int lengthDataBits = binaryData.length * EIGHTBIT;
  96. int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
  97. int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
  98. byte encodedData[] = null;
  99. int encodedDataLength = 0;
  100. int nbrChunks = 0;
  101. if (fewerThan24bits != 0) {
  102. //data not divisible by 24 bit
  103. encodedDataLength = (numberTriplets + 1) * 4;
  104. } else {
  105. // 16 or 8 bit
  106. encodedDataLength = numberTriplets * 4;
  107. }
  108. // If the output is to be "chunked" into 76 character sections,
  109. // for compliance with RFC 2045 MIME, then it is important to
  110. // allow for extra length to account for the separator(s)
  111. if (isChunked) {
  112. nbrChunks =
  113. (CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE));
  114. encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
  115. }
  116. encodedData = new byte[encodedDataLength];
  117. byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
  118. int encodedIndex = 0;
  119. int dataIndex = 0;
  120. int i = 0;
  121. int nextSeparatorIndex = CHUNK_SIZE;
  122. int chunksSoFar = 0;
  123. //log.debug("number of triplets = " + numberTriplets);
  124. for (i = 0; i < numberTriplets; i++) {
  125. dataIndex = i * 3;
  126. b1 = binaryData[dataIndex];
  127. b2 = binaryData[dataIndex + 1];
  128. b3 = binaryData[dataIndex + 2];
  129. //log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);
  130. l = (byte) (b2 & 0x0f);
  131. k = (byte) (b1 & 0x03);
  132. byte val1 =
  133. ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  134. byte val2 =
  135. ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
  136. byte val3 =
  137. ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
  138. encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
  139. //log.debug( "val2 = " + val2 );
  140. //log.debug( "k4 = " + (k<<4) );
  141. //log.debug( "vak = " + (val2 | (k<<4)) );
  142. encodedData[encodedIndex + 1] =
  143. lookUpBase64Alphabet[val2 | (k << 4)];
  144. encodedData[encodedIndex + 2] =
  145. lookUpBase64Alphabet[(l << 2) | val3];
  146. encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
  147. encodedIndex += 4;
  148. // If we are chunking, let's put a chunk separator down.
  149. if (isChunked) {
  150. // this assumes that CHUNK_SIZE % 4 == 0
  151. if (encodedIndex == nextSeparatorIndex) {
  152. System.arraycopy(
  153. CHUNK_SEPARATOR,
  154. 0,
  155. encodedData,
  156. encodedIndex,
  157. CHUNK_SEPARATOR.length);
  158. chunksSoFar++;
  159. nextSeparatorIndex =
  160. (CHUNK_SIZE * (chunksSoFar + 1)) +
  161. (chunksSoFar * CHUNK_SEPARATOR.length);
  162. encodedIndex += CHUNK_SEPARATOR.length;
  163. }
  164. }
  165. }
  166. // form integral number of 6-bit groups
  167. dataIndex = i * 3;
  168. if (fewerThan24bits == EIGHTBIT) {
  169. b1 = binaryData[dataIndex];
  170. k = (byte) (b1 & 0x03);
  171. //log.debug("b1=" + b1);
  172. //log.debug("b1<<2 = " + (b1>>2) );
  173. byte val1 =
  174. ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  175. encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
  176. encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
  177. encodedData[encodedIndex + 2] = PAD;
  178. encodedData[encodedIndex + 3] = PAD;
  179. } else if (fewerThan24bits == SIXTEENBIT) {
  180. b1 = binaryData[dataIndex];
  181. b2 = binaryData[dataIndex + 1];
  182. l = (byte) (b2 & 0x0f);
  183. k = (byte) (b1 & 0x03);
  184. byte val1 =
  185. ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  186. byte val2 =
  187. ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
  188. encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
  189. encodedData[encodedIndex + 1] =
  190. lookUpBase64Alphabet[val2 | (k << 4)];
  191. encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
  192. encodedData[encodedIndex + 3] = PAD;
  193. }
  194. if (isChunked) {
  195. // we also add a separator to the end of the final chunk.
  196. if (chunksSoFar < nbrChunks) {
  197. System.arraycopy(
  198. CHUNK_SEPARATOR,
  199. 0,
  200. encodedData,
  201. encodedDataLength - CHUNK_SEPARATOR.length,
  202. CHUNK_SEPARATOR.length);
  203. }
  204. }
  205. return encodedData;
  206. }
  207. /** * Decodes Base64 data into octects * * @param base64Data Byte array containing Base64 data * @return Array containing decoded data. */
  208. public static byte[] decodeBase64(byte[] base64Data) {
  209. // RFC 2045 requires that we discard ALL non-Base64 characters
  210. base64Data = discardNonBase64(base64Data);
  211. // handle the edge case, so we don't have to worry about it later
  212. if (base64Data.length == 0) {
  213. return new byte[0];
  214. }
  215. int numberQuadruple = base64Data.length / FOURBYTE;
  216. byte decodedData[] = null;
  217. byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
  218. // Throw away anything not in base64Data
  219. int encodedIndex = 0;
  220. int dataIndex = 0;
  221. {
  222. // this sizes the output array properly - rlw
  223. int lastData = base64Data.length;
  224. // ignore the '=' padding
  225. while (base64Data[lastData - 1] == PAD) {
  226. if (--lastData == 0) {
  227. return new byte[0];
  228. }
  229. }
  230. decodedData = new byte[lastData - numberQuadruple];
  231. }
  232. for (int i = 0; i < numberQuadruple; i++) {
  233. dataIndex = i * 4;
  234. marker0 = base64Data[dataIndex + 2];
  235. marker1 = base64Data[dataIndex + 3];
  236. b1 = base64Alphabet[base64Data[dataIndex]];
  237. b2 = base64Alphabet[base64Data[dataIndex + 1]];
  238. if (marker0 != PAD && marker1 != PAD) {
  239. //No PAD e.g 3cQl
  240. b3 = base64Alphabet[marker0];
  241. b4 = base64Alphabet[marker1];
  242. decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
  243. decodedData[encodedIndex + 1] =
  244. (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  245. decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
  246. } else if (marker0 == PAD) {
  247. //Two PAD e.g. 3c[Pad][Pad]
  248. decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
  249. } else if (marker1 == PAD) {
  250. //One PAD e.g. 3cQ[Pad]
  251. b3 = base64Alphabet[marker0];
  252. decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
  253. decodedData[encodedIndex + 1] =
  254. (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  255. }
  256. encodedIndex += 3;
  257. }
  258. return decodedData;
  259. }
  260. /** * Discards any whitespace from a base-64 encoded block. * * @param data The base-64 encoded data to discard the whitespace * from. * @return The data, less whitespace (see RFC 2045). */
  261. static byte[] discardWhitespace(byte[] data) {
  262. byte groomedData[] = new byte[data.length];
  263. int bytesCopied = 0;
  264. for (int i = 0; i < data.length; i++) {
  265. switch (data[i]) {
  266. case (byte) ' ' :
  267. case (byte) '\n' :
  268. case (byte) '\r' :
  269. case (byte) '\t' :
  270. break;
  271. default:
  272. groomedData[bytesCopied++] = data[i];
  273. }
  274. }
  275. byte packedData[] = new byte[bytesCopied];
  276. System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
  277. return packedData;
  278. }
  279. /** * Discards any characters outside of the base64 alphabet, per * the requirements on page 25 of RFC 2045 - "Any characters * outside of the base64 alphabet are to be ignored in base64 * encoded data." * * @param data The base-64 encoded data to groom * @return The data, less non-base64 characters (see RFC 2045). */
  280. static byte[] discardNonBase64(byte[] data) {
  281. byte groomedData[] = new byte[data.length];
  282. int bytesCopied = 0;
  283. for (int i = 0; i < data.length; i++) {
  284. if (isBase64(data[i])) {
  285. groomedData[bytesCopied++] = data[i];
  286. }
  287. }
  288. byte packedData[] = new byte[bytesCopied];
  289. System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
  290. return packedData;
  291. }
  292. /** * Encodes a byte[] containing binary data, into a byte[] containing * characters in the Base64 alphabet. * * @param pArray a byte array containing binary data * @return A byte array containing only Base64 character data */
  293. public static byte[] encode(byte[] pArray) {
  294. return encodeBase64(pArray, false);
  295. }
  296. public static String decode(String cryptoStr) throws
  297. UnsupportedEncodingException {
  298. if(cryptoStr.length()<40)
  299. return "";
  300. try
  301. {
  302. String tempStr = new String(decode(cryptoStr.getBytes("UTF-8")));
  303. String result = tempStr.substring(40, tempStr.length());
  304. return new String(decode(result.getBytes("UTF-8")));
  305. }
  306. catch(ArrayIndexOutOfBoundsException ex)
  307. {
  308. return "";
  309. }
  310. }
  311. /** * Decodes Base64 data into octects * * @param encoded string containing Base64 data * @return Array containind decoded data. */
  312. public static byte[] decode2(String encoded) {
  313. if (encoded == null) {
  314. return null;
  315. }
  316. char[] base64Data = encoded.toCharArray();
  317. // remove white spaces
  318. int len = removeWhiteSpace(base64Data);
  319. if (len % FOURBYTE != 0) {
  320. return null;//should be divisible by four
  321. }
  322. int numberQuadruple = (len / FOURBYTE);
  323. if (numberQuadruple == 0) {
  324. return new byte[0];
  325. }
  326. byte decodedData[] = null;
  327. byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
  328. char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
  329. int i = 0;
  330. int encodedIndex = 0;
  331. int dataIndex = 0;
  332. decodedData = new byte[(numberQuadruple) * 3];
  333. for (; i < numberQuadruple - 1; i++) {
  334. if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
  335. || !isData((d3 = base64Data[dataIndex++]))
  336. || !isData((d4 = base64Data[dataIndex++]))) {
  337. return null;
  338. }//if found "no data" just return null
  339. b1 = base64Alphabet[d1];
  340. b2 = base64Alphabet[d2];
  341. b3 = base64Alphabet[d3];
  342. b4 = base64Alphabet[d4];
  343. decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  344. decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  345. decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
  346. }
  347. if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
  348. return null;//if found "no data" just return null
  349. }
  350. b1 = base64Alphabet[d1];
  351. b2 = base64Alphabet[d2];
  352. d3 = base64Data[dataIndex++];
  353. d4 = base64Data[dataIndex++];
  354. if (!isData((d3)) || !isData((d4))) {
  355. //Check if they are PAD characters
  356. if (isPad(d3) && isPad(d4)) {
  357. if ((b2 & 0xf) != 0)//last 4 bits should be zero
  358. {
  359. return null;
  360. }
  361. byte[] tmp = new byte[i * 3 + 1];
  362. System.arraycopy(decodedData, 0, tmp, 0, i * 3);
  363. tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
  364. return tmp;
  365. } else if (!isPad(d3) && isPad(d4)) {
  366. b3 = base64Alphabet[d3];
  367. if ((b3 & 0x3) != 0)//last 2 bits should be zero
  368. {
  369. return null;
  370. }
  371. byte[] tmp = new byte[i * 3 + 2];
  372. System.arraycopy(decodedData, 0, tmp, 0, i * 3);
  373. tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  374. tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  375. return tmp;
  376. } else {
  377. return null;
  378. }
  379. } else { //No PAD e.g 3cQl
  380. b3 = base64Alphabet[d3];
  381. b4 = base64Alphabet[d4];
  382. decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  383. decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  384. decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
  385. }
  386. return decodedData;
  387. }
  388. private static boolean isWhiteSpace(char octect) {
  389. return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
  390. }
  391. private static boolean isData(char octect) {
  392. return (octect < BASELENGTH && base64Alphabet[octect] != -1);
  393. }
  394. private static boolean isPad(char octect) {
  395. return (octect == PAD);
  396. }
  397. /** * remove WhiteSpace from MIME containing encoded Base64 data. * * @param data the byte array of base64 data (with WS) * @return the new length */
  398. private static int removeWhiteSpace(char[] data) {
  399. if (data == null) {
  400. return 0;
  401. }
  402. // count characters that's not whitespace
  403. int newSize = 0;
  404. int len = data.length;
  405. for (int i = 0; i < len; i++) {
  406. if (!isWhiteSpace(data[i])) {
  407. data[newSize++] = data[i];
  408. }
  409. }
  410. return newSize;
  411. }
  412. }

Decipher工具类:

  1. package com.alex.util;
  2. import java.security.PrivateKey;
  3. import java.security.PublicKey;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import java.util.Random;
  7. public class Decipher {
  8. /** * 解密 * * @param merchant_id * @param data * @param encryptkey * @return * @throws */
  9. public static String decryptData(Map<String, String> map) throws Exception {
  10. String encryptkey = map.get("encryptkey");
  11. String data = map.get("data");
  12. // 获取自己私钥解密
  13. PrivateKey pvkformPfx = RSA.getPvkformPfx("F:\\miyao\\demo\\user-rsa.pfx",
  14. "123456");
  15. String decryptData = RSA.decrypt(encryptkey, pvkformPfx);
  16. String post = AES.decryptFromBase64(data, decryptData);
  17. return post;
  18. }
  19. /** * 加密 * * @param merchant_id * @param data * @param encryptkey * @return * @throws */
  20. public static Map<String, String> encryptData(String json) throws Exception {
  21. System.out.println("json数据=============>" + json);
  22. // 获取公钥
  23. PublicKey pubKeyFromCrt = RSA.getPubKeyFromCRT("F:\\miyao\\demo\\public-rsa.cer");
  24. // 随机生成16数字
  25. String key = getRandom(16);
  26. // 使用RSA算法将自己随机生成的AESkey加密
  27. String encryptKey = RSA.encrypt(key, pubKeyFromCrt);
  28. // 使用AES算法用随机生成的AESkey,对json串进行加密
  29. String encryData = AES.encryptToBase64(json, key);
  30. System.out.println("密文key============>" + encryptKey);
  31. System.out.println("密文数据===========>" + encryData);
  32. Map<String, String> map = new HashMap<String, String>();
  33. map.put("data", encryData);
  34. map.put("encryptkey", encryptKey);
  35. return map;
  36. }
  37. public static Random random = new Random();
  38. public static String getRandom(int length) {
  39. StringBuilder ret = new StringBuilder();
  40. for (int i = 0; i < length; i++) {
  41. boolean isChar = (random.nextInt(2) % 2 == 0);// 输出字母还是数字
  42. if (isChar) { // 字符串
  43. int choice = (random.nextInt(2) % 2 == 0) ? 65 : 97; // 取得大写字母还是小写字母
  44. ret.append((char) (choice + random.nextInt(26)));
  45. } else { // 数字
  46. ret.append(Integer.toString(random.nextInt(10)));
  47. }
  48. }
  49. return ret.toString();
  50. }
  51. public static void main(String[] args) {
  52. }
  53. }

RSA工具类:

  1. package com.alex.util;
  2. /* --------------------------------------------**********-------------------------------------------- 该算法于1977年由美国麻省理工学院MIT(Massachusetts Institute of Technology)的Ronal Rivest,Adi Shamir和Len Adleman三位年轻教授提出,并以三人的姓氏Rivest,Shamir和Adlernan命名为RSA算法,是一个支持变长密钥的公共密钥算法,需要加密的文件快的长度也是可变的! 所谓RSA加密算法,是世界上第一个非对称加密算法,也是数论的第一个实际应用。它的算法如下: 1.找两个非常大的质数p和q(通常p和q都有155十进制位或都有512十进制位)并计算n=pq,k=(p-1)(q-1)。 2.将明文编码成整数M,保证M不小于0但是小于n。 3.任取一个整数e,保证e和k互质,而且e不小于0但是小于k。加密钥匙(称作公钥)是(e, n)。 4.找到一个整数d,使得ed除以k的余数是1(只要e和n满足上面条件,d肯定存在)。解密钥匙(称作密钥)是(d, n)。 加密过程: 加密后的编码C等于M的e次方除以n所得的余数。 解密过程: 解密后的编码N等于C的d次方除以n所得的余数。 只要e、d和n满足上面给定的条件。M等于N。 --------------------------------------------**********-------------------------------------------- */
  3. import javax.crypto.Cipher;
  4. import org.apache.commons.lang.StringUtils;
  5. import java.io.FileInputStream;
  6. import java.io.InputStream;
  7. import java.math.BigInteger;
  8. import java.security.*;
  9. import java.security.cert.Certificate;
  10. import java.security.cert.CertificateFactory;
  11. import java.security.interfaces.RSAPublicKey;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14. import java.util.Enumeration;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. import java.util.TreeMap;
  18. public class RSA {
  19. /** 指定key的大小 */
  20. private static int KEYSIZE = 1024;
  21. public static final String CHAR_ENCODING = "UTF-8";
  22. public static final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
  23. /** * 生成密钥对 */
  24. public static Map<String, String> generateKeyPair() throws Exception {
  25. /** RSA算法要求有一个可信任的随机数源 */
  26. SecureRandom sr = new SecureRandom();
  27. /** 为RSA算法创建一个KeyPairGenerator对象 */
  28. KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
  29. /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
  30. kpg.initialize(KEYSIZE, sr);
  31. /** 生成密匙对 */
  32. KeyPair kp = kpg.generateKeyPair();
  33. /** 得到公钥 */
  34. Key publicKey = kp.getPublic();
  35. byte[] publicKeyBytes = publicKey.getEncoded();
  36. String pub = new String(Base64.encodeBase64(publicKeyBytes),
  37. CHAR_ENCODING);
  38. /** 得到私钥 */
  39. Key privateKey = kp.getPrivate();
  40. byte[] privateKeyBytes = privateKey.getEncoded();
  41. String pri = new String(Base64.encodeBase64(privateKeyBytes),
  42. CHAR_ENCODING);
  43. Map<String, String> map = new HashMap<String, String>();
  44. map.put("publicKey", pub);
  45. map.put("privateKey", pri);
  46. RSAPublicKey rsp = (RSAPublicKey) kp.getPublic();
  47. BigInteger bint = rsp.getModulus();
  48. byte[] b = bint.toByteArray();
  49. byte[] deBase64Value = Base64.encodeBase64(b);
  50. String retValue = new String(deBase64Value);
  51. map.put("modulus", retValue);
  52. return map;
  53. }
  54. /** * 通过PFX文件获得私钥 * * @param //文件路径 * @param //PFX密码 * @return PrivateKey */
  55. public static PrivateKey getPvkformPfx(String strPfx, String strPassword)
  56. throws Exception {
  57. PrivateKey prikey = null;
  58. char[] nPassword = null;
  59. if ((strPassword == null) || strPassword.trim().equals("")) {
  60. nPassword = null;
  61. } else {
  62. nPassword = strPassword.toCharArray();
  63. }
  64. KeyStore ks = getKsformPfx(strPfx, strPassword);
  65. String keyAlias = getAlsformPfx(strPfx, strPassword);
  66. prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);
  67. return prikey;
  68. }
  69. /** * 通过PFX文件获得KEYSTORE * * @param //文件路径 * @param //PFX密码 * @return KeyStore */
  70. public static KeyStore getKsformPfx(String strPfx, String strPassword)
  71. throws Exception {
  72. FileInputStream fis = null;
  73. Security
  74. .addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
  75. KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
  76. fis = new FileInputStream(strPfx);
  77. // If the keystore password is empty(""), then we have to set
  78. // to null, otherwise it won't work!!!
  79. char[] nPassword = null;
  80. if ((strPassword == null) || strPassword.trim().equals("")) {
  81. nPassword = null;
  82. } else {
  83. nPassword = strPassword.toCharArray();
  84. }
  85. ks.load(fis, nPassword);
  86. if (null != fis) {
  87. fis.close();
  88. }
  89. return ks;
  90. }
  91. /** * 通过PFX文件获得别名 * * @param //文件路径 * @param //PFX密码 * @return 别名 */
  92. public static String getAlsformPfx(String strPfx, String strPassword)
  93. throws Exception {
  94. String keyAlias = null;
  95. KeyStore ks = getKsformPfx(strPfx, strPassword);
  96. Enumeration<String> enumas = ks.aliases();
  97. keyAlias = null;
  98. // we are readin just one certificate.
  99. if (enumas.hasMoreElements()) {
  100. keyAlias = (String) enumas.nextElement();
  101. }
  102. return keyAlias;
  103. }
  104. /** * 获取公钥 */
  105. public static PublicKey getPubKeyFromCRT(String crtFileName) throws Exception {
  106. InputStream is = new FileInputStream(crtFileName);
  107. CertificateFactory cf = CertificateFactory.getInstance("x509");
  108. Certificate cerCert = cf.generateCertificate(is);
  109. return cerCert.getPublicKey();
  110. }
  111. /** * 加密方法 source: 源数据 */
  112. public static String encrypt(String source, String publicKey)
  113. throws Exception {
  114. Key key = getPublicKey(publicKey);
  115. /** 得到Cipher对象来实现对源数据的RSA加密 */
  116. Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
  117. cipher.init(Cipher.ENCRYPT_MODE, key);
  118. byte[] b = source.getBytes();
  119. /** 执行加密操作 */
  120. byte[] b1 = cipher.doFinal(b);
  121. return new String(Base64.encodeBase64(b1),
  122. CHAR_ENCODING);
  123. }
  124. /** * 加密方法 source: 源数据 */
  125. public static String encrypt(String source, PublicKey pubKeyFromCrt)
  126. throws Exception {
  127. Key key = pubKeyFromCrt;
  128. /** 得到Cipher对象来实现对源数据的RSA加密 */
  129. Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
  130. cipher.init(Cipher.ENCRYPT_MODE, key);
  131. byte[] b = source.getBytes();
  132. /** 执行加密操作 */
  133. byte[] b1 = cipher.doFinal(b);
  134. return new String(Base64.encodeBase64(b1),
  135. CHAR_ENCODING);
  136. }
  137. /** * 解密算法 cryptograph:密文 */
  138. public static String decrypt(String cryptograph, PrivateKey privateKey)
  139. throws Exception {
  140. Key key = privateKey;
  141. /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
  142. Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
  143. cipher.init(Cipher.DECRYPT_MODE, key);
  144. byte[] b1 = Base64.decodeBase64(cryptograph.getBytes());
  145. /** 执行解密操作 */
  146. byte[] b = cipher.doFinal(b1);
  147. return new String(b);
  148. }
  149. /** * 得到公钥 * * @param key * 密钥字符串(经过base64编码) * @throws Exception */
  150. public static PublicKey getPublicKey(String key) throws Exception {
  151. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(
  152. Base64.decodeBase64(key.getBytes()));
  153. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  154. PublicKey publicKey = keyFactory.generatePublic(keySpec);
  155. return publicKey;
  156. }
  157. /** * 得到私钥 * * @param key * 密钥字符串(经过base64编码) * @throws Exception */
  158. public static PrivateKey getPrivateKey(String key) throws Exception {
  159. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
  160. Base64.decodeBase64(key.getBytes()));
  161. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  162. PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  163. return privateKey;
  164. }
  165. /** * 签名 */
  166. public static String sign(String content, String privateKey) {
  167. String charset = CHAR_ENCODING;
  168. try {
  169. PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
  170. Base64.decodeBase64(privateKey.getBytes()));
  171. KeyFactory keyf = KeyFactory.getInstance("RSA");
  172. PrivateKey priKey = keyf.generatePrivate(priPKCS8);
  173. Signature signature = Signature.getInstance("SHA1WithRSA");
  174. signature.initSign(priKey);
  175. signature.update(content.getBytes(charset));
  176. byte[] signed = signature.sign();
  177. return new String(Base64.encodeBase64(signed));
  178. } catch (Exception e) {
  179. }
  180. return null;
  181. }
  182. /** * 验签 */
  183. public static boolean checkSign(String content, String sign, String publicKey)
  184. {
  185. try
  186. {
  187. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  188. byte[] encodedKey = Base64.decode2(publicKey);
  189. PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  190. Signature signature = Signature
  191. .getInstance("SHA1WithRSA");
  192. signature.initVerify(pubKey);
  193. signature.update( content.getBytes("utf-8") );
  194. boolean bverify = signature.verify( Base64.decode2(sign) );
  195. return bverify;
  196. }
  197. catch (Exception e)
  198. {
  199. e.printStackTrace();
  200. }
  201. return false;
  202. }
  203. /** * 生成RSA签名 */
  204. public static String handleRSA(TreeMap<String, Object> map,
  205. String privateKey) {
  206. StringBuffer sbuffer = new StringBuffer();
  207. for (Map.Entry<String, Object> entry : map.entrySet()) {
  208. sbuffer.append(entry.getValue());
  209. }
  210. String signTemp = sbuffer.toString();
  211. String sign = "";
  212. if (StringUtils.isNotEmpty(privateKey)) {
  213. sign = RSA.sign(signTemp, privateKey);
  214. }
  215. return sign;
  216. }
  217. /** * 解密算法 cryptograph:密文 */
  218. public static String decrypt(String cryptograph, String privateKey)
  219. throws Exception {
  220. Key key = getPrivateKey(privateKey);
  221. /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
  222. Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  223. cipher.init(Cipher.DECRYPT_MODE, key);
  224. byte[] b1 = Base64.decodeBase64(cryptograph.getBytes());
  225. /** 执行解密操作 */
  226. byte[] b = cipher.doFinal(b1);
  227. return new String(b);
  228. }
  229. }

测试类:

  1. package com.alex.util;
  2. import java.util.Map;
  3. public class RSATest {
  4. public static void main(String[] args) throws Exception {
  5. String reqStr = "加密证书和RSA加密解密";
  6. //加密
  7. Map<String,String> map = Decipher.encryptData(reqStr);
  8. //解密
  9. String respStr = Decipher.decryptData(map);
  10. System.out.println("解密后的数据为=============>" + respStr);
  11. }
  12. }

结果:
这里写图片描述

源码下载:http://download.csdn.net/detail/qq_32347977/9444440

发表评论

表情:
评论列表 (有 0 条评论,220人围观)

还没有评论,来说两句吧...

相关阅读

    相关 RSA加密解密

    RSA加密与解密 RSA算法的密钥由公钥和私钥组成,公钥用于加密,私钥用于解密。顾名思义,公钥就是可以进行公开的密钥,一般可以公开给你的合作伙伴;私钥就是私有的,也就是只

    相关 加密解密、签名、证书

    一、网络安全 数据传输安全的要满足的要求: 消息的发送方能够确定消息只有预期的接收方可以解密(不保证第三方无法获得,但保证第三方无法解密)。 消息的接收方可以确定消息是由

    相关 JS-RSA加密解密

      在上一篇文章《Java使用RSA加密解密签名及校验》中,用java实现加密解密,但是在实际应用中,如前端页面用户输入的密码传输给后台服务前,需加密,也就是公钥加密,私钥解密