RSA密钥生成、加密解密、签名验签

时间:2022-02-06 21:39:23

RSA 非对称加密
公钥加密,私钥解密

私钥签名,公钥验签

下面是生成随机密钥对:

  1. //随机生成密钥对
  2. KeyPairGenerator keyPairGen = null;
  3. try {
  4. keyPairGen = KeyPairGenerator.getInstance("RSA");
  5. } catch (NoSuchAlgorithmException e) {
  6. // TODO Auto-generated catch block
  7. e.printStackTrace();
  8. }
  9. // 初始化密钥对生成器,密钥大小为96-1024位
  10. keyPairGen.initialize(1024, new SecureRandom());
  11. // 生成一个密钥对,保存在keyPair中
  12. KeyPair keyPair = keyPairGen.generateKeyPair();
  13. // 得到私钥
  14. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  15. // 得到公钥
  16. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  17. String publicKeyString = Base64.encode(publicKey.getEncoded());
  18. // 得到私钥字符串
  19. String privateKeyString = Base64.encode(privateKey.getEncoded());

加密解密:

  1. /**
  2. * Bestpay.com.cn Inc.
  3. * Copyright (c) 2011-2016 All Rights Reserved.
  4. */
  5. package com.bestpay.posprouter.utils;/**
  6. * Created by lxn on 2016/7/21.
  7. */
  8. import java.io.BufferedReader;
  9. import java.io.BufferedWriter;
  10. import java.io.FileReader;
  11. import java.io.FileWriter;
  12. import java.io.IOException;
  13. import java.security.InvalidKeyException;
  14. import java.security.KeyFactory;
  15. import java.security.KeyPair;
  16. import java.security.KeyPairGenerator;
  17. import java.security.NoSuchAlgorithmException;
  18. import java.security.SecureRandom;
  19. import java.security.interfaces.RSAPrivateKey;
  20. import java.security.interfaces.RSAPublicKey;
  21. import java.security.spec.InvalidKeySpecException;
  22. import java.security.spec.PKCS8EncodedKeySpec;
  23. import java.security.spec.X509EncodedKeySpec;
  24. import javax.crypto.BadPaddingException;
  25. import javax.crypto.Cipher;
  26. import javax.crypto.IllegalBlockSizeException;
  27. import javax.crypto.NoSuchPaddingException;
  28. public class RSAEncrypt {
  29. /**
  30. * 字节数据转字符串专用集合
  31. */
  32. private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
  33. '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  34. /**
  35. * 随机生成密钥对
  36. */
  37. public static void genKeyPair(String filePath) {
  38. // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
  39. KeyPairGenerator keyPairGen = null;
  40. try {
  41. keyPairGen = KeyPairGenerator.getInstance("RSA");
  42. } catch (NoSuchAlgorithmException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. // 初始化密钥对生成器,密钥大小为96-1024位
  47. keyPairGen.initialize(1024,new SecureRandom());
  48. // 生成一个密钥对,保存在keyPair中
  49. KeyPair keyPair = keyPairGen.generateKeyPair();
  50. // 得到私钥
  51. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  52. // 得到公钥
  53. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  54. try {
  55. // 得到公钥字符串
  56. String publicKeyString = Base64.encode(publicKey.getEncoded());
  57. // 得到私钥字符串
  58. String privateKeyString = Base64.encode(privateKey.getEncoded());
  59. // 将密钥对写入到文件
  60. FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");
  61. FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");
  62. BufferedWriter pubbw = new BufferedWriter(pubfw);
  63. BufferedWriter pribw = new BufferedWriter(prifw);
  64. pubbw.write(publicKeyString);
  65. pribw.write(privateKeyString);
  66. pubbw.flush();
  67. pubbw.close();
  68. pubfw.close();
  69. pribw.flush();
  70. pribw.close();
  71. prifw.close();
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. /**
  77. * 从文件中输入流中加载公钥
  78. *
  79. * @param in
  80. *            公钥输入流
  81. * @throws Exception
  82. *             加载公钥时产生的异常
  83. */
  84. public static String loadPublicKeyByFile(String path) throws Exception {
  85. try {
  86. BufferedReader br = new BufferedReader(new FileReader(path
  87. + "/publicKey.keystore"));
  88. String readLine = null;
  89. StringBuilder sb = new StringBuilder();
  90. while ((readLine = br.readLine()) != null) {
  91. sb.append(readLine);
  92. }
  93. br.close();
  94. return sb.toString();
  95. } catch (IOException e) {
  96. throw new Exception("公钥数据流读取错误");
  97. } catch (NullPointerException e) {
  98. throw new Exception("公钥输入流为空");
  99. }
  100. }
  101. /**
  102. * 从字符串中加载公钥
  103. *
  104. * @param publicKeyStr
  105. *            公钥数据字符串
  106. * @throws Exception
  107. *             加载公钥时产生的异常
  108. */
  109. public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
  110. throws Exception {
  111. try {
  112. byte[] buffer = Base64.decode(publicKeyStr);
  113. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  114. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
  115. return (RSAPublicKey) keyFactory.generatePublic(keySpec);
  116. } catch (NoSuchAlgorithmException e) {
  117. throw new Exception("无此算法");
  118. } catch (InvalidKeySpecException e) {
  119. throw new Exception("公钥非法");
  120. } catch (NullPointerException e) {
  121. throw new Exception("公钥数据为空");
  122. }
  123. }
  124. /**
  125. * 从文件中加载私钥
  126. *
  127. * @param keyFileName
  128. *            私钥文件名
  129. * @return 是否成功
  130. * @throws Exception
  131. */
  132. public static String loadPrivateKeyByFile(String path) throws Exception {
  133. try {
  134. BufferedReader br = new BufferedReader(new FileReader(path
  135. + "/privateKey.keystore"));
  136. String readLine = null;
  137. StringBuilder sb = new StringBuilder();
  138. while ((readLine = br.readLine()) != null) {
  139. sb.append(readLine);
  140. }
  141. br.close();
  142. return sb.toString();
  143. } catch (IOException e) {
  144. throw new Exception("私钥数据读取错误");
  145. } catch (NullPointerException e) {
  146. throw new Exception("私钥输入流为空");
  147. }
  148. }
  149. public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
  150. throws Exception {
  151. try {
  152. byte[] buffer = Base64.decode(privateKeyStr);
  153. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
  154. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  155. return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
  156. } catch (NoSuchAlgorithmException e) {
  157. throw new Exception("无此算法");
  158. } catch (InvalidKeySpecException e) {
  159. throw new Exception("私钥非法");
  160. } catch (NullPointerException e) {
  161. throw new Exception("私钥数据为空");
  162. }
  163. }
  164. /**
  165. * 公钥加密过程
  166. *
  167. * @param publicKey
  168. *            公钥
  169. * @param plainTextData
  170. *            明文数据
  171. * @return
  172. * @throws Exception
  173. *             加密过程中的异常信息
  174. */
  175. public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
  176. throws Exception {
  177. if (publicKey == null) {
  178. throw new Exception("加密公钥为空, 请设置");
  179. }
  180. Cipher cipher = null;
  181. try {
  182. // 使用默认RSA
  183. cipher = Cipher.getInstance("RSA");
  184. // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
  185. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  186. byte[] output = cipher.doFinal(plainTextData);
  187. return output;
  188. } catch (NoSuchAlgorithmException e) {
  189. throw new Exception("无此加密算法");
  190. } catch (NoSuchPaddingException e) {
  191. e.printStackTrace();
  192. return null;
  193. } catch (InvalidKeyException e) {
  194. throw new Exception("加密公钥非法,请检查");
  195. } catch (IllegalBlockSizeException e) {
  196. throw new Exception("明文长度非法");
  197. } catch (BadPaddingException e) {
  198. throw new Exception("明文数据已损坏");
  199. }
  200. }
  201. /**
  202. * 私钥加密过程
  203. *
  204. * @param privateKey
  205. *            私钥
  206. * @param plainTextData
  207. *            明文数据
  208. * @return
  209. * @throws Exception
  210. *             加密过程中的异常信息
  211. */
  212. public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)
  213. throws Exception {
  214. if (privateKey == null) {
  215. throw new Exception("加密私钥为空, 请设置");
  216. }
  217. Cipher cipher = null;
  218. try {
  219. // 使用默认RSA
  220. cipher = Cipher.getInstance("RSA");
  221. cipher.init(Cipher.ENCRYPT_MODE, privateKey);
  222. byte[] output = cipher.doFinal(plainTextData);
  223. return output;
  224. } catch (NoSuchAlgorithmException e) {
  225. throw new Exception("无此加密算法");
  226. } catch (NoSuchPaddingException e) {
  227. e.printStackTrace();
  228. return null;
  229. } catch (InvalidKeyException e) {
  230. throw new Exception("加密私钥非法,请检查");
  231. } catch (IllegalBlockSizeException e) {
  232. throw new Exception("明文长度非法");
  233. } catch (BadPaddingException e) {
  234. throw new Exception("明文数据已损坏");
  235. }
  236. }
  237. /**
  238. * 私钥解密过程
  239. *
  240. * @param privateKey
  241. *            私钥
  242. * @param cipherData
  243. *            密文数据
  244. * @return 明文
  245. * @throws Exception
  246. *             解密过程中的异常信息
  247. */
  248. public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
  249. throws Exception {
  250. if (privateKey == null) {
  251. throw new Exception("解密私钥为空, 请设置");
  252. }
  253. Cipher cipher = null;
  254. try {
  255. // 使用默认RSA
  256. cipher = Cipher.getInstance("RSA");
  257. // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
  258. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  259. byte[] output = cipher.doFinal(cipherData);
  260. return output;
  261. } catch (NoSuchAlgorithmException e) {
  262. throw new Exception("无此解密算法");
  263. } catch (NoSuchPaddingException e) {
  264. e.printStackTrace();
  265. return null;
  266. } catch (InvalidKeyException e) {
  267. throw new Exception("解密私钥非法,请检查");
  268. } catch (IllegalBlockSizeException e) {
  269. throw new Exception("密文长度非法");
  270. } catch (BadPaddingException e) {
  271. throw new Exception("密文数据已损坏");
  272. }
  273. }
  274. /**
  275. * 公钥解密过程
  276. *
  277. * @param publicKey
  278. *            公钥
  279. * @param cipherData
  280. *            密文数据
  281. * @return 明文
  282. * @throws Exception
  283. *             解密过程中的异常信息
  284. */
  285. public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)
  286. throws Exception {
  287. if (publicKey == null) {
  288. throw new Exception("解密公钥为空, 请设置");
  289. }
  290. Cipher cipher = null;
  291. try {
  292. // 使用默认RSA
  293. cipher = Cipher.getInstance("RSA");
  294. // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
  295. cipher.init(Cipher.DECRYPT_MODE, publicKey);
  296. byte[] output = cipher.doFinal(cipherData);
  297. return output;
  298. } catch (NoSuchAlgorithmException e) {
  299. throw new Exception("无此解密算法");
  300. } catch (NoSuchPaddingException e) {
  301. e.printStackTrace();
  302. return null;
  303. } catch (InvalidKeyException e) {
  304. throw new Exception("解密公钥非法,请检查");
  305. } catch (IllegalBlockSizeException e) {
  306. throw new Exception("密文长度非法");
  307. } catch (BadPaddingException e) {
  308. throw new Exception("密文数据已损坏");
  309. }
  310. }
  311. /**
  312. * 字节数据转十六进制字符串
  313. *
  314. * @param data
  315. *            输入数据
  316. * @return 十六进制内容
  317. */
  318. public static String byteArrayToString(byte[] data) {
  319. StringBuilder stringBuilder = new StringBuilder();
  320. for (int i = 0; i < data.length; i++) {
  321. // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
  322. stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
  323. // 取出字节的低四位 作为索引得到相应的十六进制标识符
  324. stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
  325. if (i < data.length - 1) {
  326. stringBuilder.append(' ');
  327. }
  328. }
  329. return stringBuilder.toString();
  330. }
  331. }

签名验签:

  1. /**
  2. * Bestpay.com.cn Inc.
  3. * Copyright (c) 2011-2016 All Rights Reserved.
  4. */
  5. package com.bestpay.posprouter.utils;/**
  6. * Created by lxn on 2016/7/21.
  7. */
  8. import java.security.KeyFactory;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.spec.PKCS8EncodedKeySpec;
  12. import java.security.spec.X509EncodedKeySpec;
  13. /**
  14. * @author lxn
  15. * @version Id: RSASignature.java, v 0.1 2016/7/21 16:14 lxn Exp $$
  16. */
  17. public class RSASignature {
  18. /**
  19. * 签名算法
  20. */
  21. public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
  22. /**
  23. * RSA签名
  24. * @param content 待签名数据
  25. * @param privateKey 商户私钥
  26. * @param encode 字符集编码
  27. * @return 签名值
  28. */
  29. public static String sign(String content, String privateKey, String encode)
  30. {
  31. try
  32. {
  33. PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );
  34. KeyFactory keyf                 = KeyFactory.getInstance("RSA");
  35. PrivateKey priKey               = keyf.generatePrivate(priPKCS8);
  36. java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  37. signature.initSign(priKey);
  38. signature.update( content.getBytes(encode));
  39. byte[] signed = signature.sign();
  40. return Base64.encode(signed);
  41. }
  42. catch (Exception e)
  43. {
  44. e.printStackTrace();
  45. }
  46. return null;
  47. }
  48. public static String sign(String content, String privateKey)
  49. {
  50. try
  51. {
  52. PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );
  53. KeyFactory keyf = KeyFactory.getInstance("RSA");
  54. PrivateKey priKey = keyf.generatePrivate(priPKCS8);
  55. java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  56. signature.initSign(priKey);
  57. signature.update( content.getBytes());
  58. byte[] signed = signature.sign();
  59. return Base64.encode(signed);
  60. }
  61. catch (Exception e)
  62. {
  63. e.printStackTrace();
  64. }
  65. return null;
  66. }
  67. /**
  68. * RSA验签名检查
  69. * @param content 待签名数据
  70. * @param sign 签名值
  71. * @param publicKey 分配给开发商公钥
  72. * @param encode 字符集编码
  73. * @return 布尔值
  74. */
  75. public static boolean doCheck(String content, String sign, String publicKey,String encode)
  76. {
  77. try
  78. {
  79. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  80. byte[] encodedKey = Base64.decode(publicKey);
  81. PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  82. java.security.Signature signature = java.security.Signature
  83. .getInstance(SIGN_ALGORITHMS);
  84. signature.initVerify(pubKey);
  85. signature.update( content.getBytes(encode) );
  86. boolean bverify = signature.verify( Base64.decode(sign) );
  87. return bverify;
  88. }
  89. catch (Exception e)
  90. {
  91. e.printStackTrace();
  92. }
  93. return false;
  94. }
  95. public static boolean doCheck(String content, String sign, String publicKey)
  96. {
  97. try
  98. {
  99. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  100. byte[] encodedKey = Base64.decode(publicKey);
  101. PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  102. java.security.Signature signature = java.security.Signature
  103. .getInstance(SIGN_ALGORITHMS);
  104. signature.initVerify(pubKey);
  105. signature.update( content.getBytes() );
  106. boolean bverify = signature.verify( Base64.decode(sign) );
  107. return bverify;
  108. }
  109. catch (Exception e)
  110. {
  111. e.printStackTrace();
  112. }
  113. return false;
  114. }
  115. }

BASE64:

  1. /**
  2. * Bestpay.com.cn Inc.
  3. * Copyright (c) 2011-2016 All Rights Reserved.
  4. */
  5. package com.bestpay.posprouter.utils;/**
  6. * Created by lxn on 2016/7/21.
  7. */
  8. /**
  9. * @author lxn
  10. * @version Id: Base64.java, v 0.1 2016/7/21 16:19 lxn Exp $$
  11. */
  12. public final class Base64 {
  13. static private final int     BASELENGTH           = 128;
  14. static private final int     LOOKUPLENGTH         = 64;
  15. static private final int     TWENTYFOURBITGROUP   = 24;
  16. static private final int     EIGHTBIT             = 8;
  17. static private final int     SIXTEENBIT           = 16;
  18. static private final int     FOURBYTE             = 4;
  19. static private final int     SIGN                 = -128;
  20. static private final char    PAD                  = '=';
  21. static private final boolean fDebug               = false;
  22. static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
  23. static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
  24. static {
  25. for (int i = 0; i < BASELENGTH; ++i) {
  26. base64Alphabet[i] = -1;
  27. }
  28. for (int i = 'Z'; i >= 'A'; i--) {
  29. base64Alphabet[i] = (byte) (i - 'A');
  30. }
  31. for (int i = 'z'; i >= 'a'; i--) {
  32. base64Alphabet[i] = (byte) (i - 'a' + 26);
  33. }
  34. for (int i = '9'; i >= '0'; i--) {
  35. base64Alphabet[i] = (byte) (i - '0' + 52);
  36. }
  37. base64Alphabet['+'] = 62;
  38. base64Alphabet['/'] = 63;
  39. for (int i = 0; i <= 25; i++) {
  40. lookUpBase64Alphabet[i] = (char) ('A' + i);
  41. }
  42. for (int i = 26, j = 0; i <= 51; i++, j++) {
  43. lookUpBase64Alphabet[i] = (char) ('a' + j);
  44. }
  45. for (int i = 52, j = 0; i <= 61; i++, j++) {
  46. lookUpBase64Alphabet[i] = (char) ('0' + j);
  47. }
  48. lookUpBase64Alphabet[62] = (char) '+';
  49. lookUpBase64Alphabet[63] = (char) '/';
  50. }
  51. private static boolean isWhiteSpace(char octect) {
  52. return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
  53. }
  54. private static boolean isPad(char octect) {
  55. return (octect == PAD);
  56. }
  57. private static boolean isData(char octect) {
  58. return (octect < BASELENGTH && base64Alphabet[octect] != -1);
  59. }
  60. /**
  61. * Encodes hex octects into Base64
  62. *
  63. * @param binaryData Array containing binaryData
  64. * @return Encoded Base64 array
  65. */
  66. public static String encode(byte[] binaryData) {
  67. if (binaryData == null) {
  68. return null;
  69. }
  70. int lengthDataBits = binaryData.length * EIGHTBIT;
  71. if (lengthDataBits == 0) {
  72. return "";
  73. }
  74. int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
  75. int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
  76. int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
  77. char encodedData[] = null;
  78. encodedData = new char[numberQuartet * 4];
  79. byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
  80. int encodedIndex = 0;
  81. int dataIndex = 0;
  82. if (fDebug) {
  83. System.out.println("number of triplets = " + numberTriplets);
  84. }
  85. for (int i = 0; i < numberTriplets; i++) {
  86. b1 = binaryData[dataIndex++];
  87. b2 = binaryData[dataIndex++];
  88. b3 = binaryData[dataIndex++];
  89. if (fDebug) {
  90. System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
  91. }
  92. l = (byte) (b2 & 0x0f);
  93. k = (byte) (b1 & 0x03);
  94. byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  95. byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
  96. byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
  97. if (fDebug) {
  98. System.out.println("val2 = " + val2);
  99. System.out.println("k4   = " + (k << 4));
  100. System.out.println("vak  = " + (val2 | (k << 4)));
  101. }
  102. encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
  103. encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
  104. encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
  105. encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
  106. }
  107. // form integral number of 6-bit groups
  108. if (fewerThan24bits == EIGHTBIT) {
  109. b1 = binaryData[dataIndex];
  110. k = (byte) (b1 & 0x03);
  111. if (fDebug) {
  112. System.out.println("b1=" + b1);
  113. System.out.println("b1<<2 = " + (b1 >> 2));
  114. }
  115. byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  116. encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
  117. encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
  118. encodedData[encodedIndex++] = PAD;
  119. encodedData[encodedIndex++] = PAD;
  120. } else if (fewerThan24bits == SIXTEENBIT) {
  121. b1 = binaryData[dataIndex];
  122. b2 = binaryData[dataIndex + 1];
  123. l = (byte) (b2 & 0x0f);
  124. k = (byte) (b1 & 0x03);
  125. byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  126. byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
  127. encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
  128. encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
  129. encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
  130. encodedData[encodedIndex++] = PAD;
  131. }
  132. return new String(encodedData);
  133. }
  134. /**
  135. * Decodes Base64 data into octects
  136. *
  137. * @param encoded string containing Base64 data
  138. * @return Array containind decoded data.
  139. */
  140. public static byte[] decode(String encoded) {
  141. if (encoded == null) {
  142. return null;
  143. }
  144. char[] base64Data = encoded.toCharArray();
  145. // remove white spaces
  146. int len = removeWhiteSpace(base64Data);
  147. if (len % FOURBYTE != 0) {
  148. return null;//should be divisible by four
  149. }
  150. int numberQuadruple = (len / FOURBYTE);
  151. if (numberQuadruple == 0) {
  152. return new byte[0];
  153. }
  154. byte decodedData[] = null;
  155. byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
  156. char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
  157. int i = 0;
  158. int encodedIndex = 0;
  159. int dataIndex = 0;
  160. decodedData = new byte[(numberQuadruple) * 3];
  161. for (; i < numberQuadruple - 1; i++) {
  162. if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
  163. || !isData((d3 = base64Data[dataIndex++]))
  164. || !isData((d4 = base64Data[dataIndex++]))) {
  165. return null;
  166. }//if found "no data" just return null
  167. b1 = base64Alphabet[d1];
  168. b2 = base64Alphabet[d2];
  169. b3 = base64Alphabet[d3];
  170. b4 = base64Alphabet[d4];
  171. decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  172. decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  173. decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
  174. }
  175. if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
  176. return null;//if found "no data" just return null
  177. }
  178. b1 = base64Alphabet[d1];
  179. b2 = base64Alphabet[d2];
  180. d3 = base64Data[dataIndex++];
  181. d4 = base64Data[dataIndex++];
  182. if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
  183. if (isPad(d3) && isPad(d4)) {
  184. if ((b2 & 0xf) != 0)//last 4 bits should be zero
  185. {
  186. return null;
  187. }
  188. byte[] tmp = new byte[i * 3 + 1];
  189. System.arraycopy(decodedData, 0, tmp, 0, i * 3);
  190. tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
  191. return tmp;
  192. } else if (!isPad(d3) && isPad(d4)) {
  193. b3 = base64Alphabet[d3];
  194. if ((b3 & 0x3) != 0)//last 2 bits should be zero
  195. {
  196. return null;
  197. }
  198. byte[] tmp = new byte[i * 3 + 2];
  199. System.arraycopy(decodedData, 0, tmp, 0, i * 3);
  200. tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  201. tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  202. return tmp;
  203. } else {
  204. return null;
  205. }
  206. } else { //No PAD e.g 3cQl
  207. b3 = base64Alphabet[d3];
  208. b4 = base64Alphabet[d4];
  209. decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  210. decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  211. decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
  212. }
  213. return decodedData;
  214. }
  215. /**
  216. * remove WhiteSpace from MIME containing encoded Base64 data.
  217. *
  218. * @param data  the byte array of base64 data (with WS)
  219. * @return      the new length
  220. */
  221. private static int removeWhiteSpace(char[] data) {
  222. if (data == null) {
  223. return 0;
  224. }
  225. // count characters that's not whitespace
  226. int newSize = 0;
  227. int len = data.length;
  228. for (int i = 0; i < len; i++) {
  229. if (!isWhiteSpace(data[i])) {
  230. data[newSize++] = data[i];
  231. }
  232. }
  233. return newSize;
  234. }
  235. }
版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/xiananliu/article/details/51996994