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

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

私钥签名,公钥验签

下面是生成随机密钥对:

[java] view plain copy
 
  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.   
  18.   
  19.        String publicKeyString = Base64.encode(publicKey.getEncoded());  
  20.        // 得到私钥字符串  
  21.        String privateKeyString = Base64.encode(privateKey.getEncoded());  

加密解密:

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

签名验签:
[java] view plain copy
 
  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. import java.security.KeyFactory;  
  10. import java.security.PrivateKey;  
  11. import java.security.PublicKey;  
  12. import java.security.spec.PKCS8EncodedKeySpec;  
  13. import java.security.spec.X509EncodedKeySpec;  
  14.   
  15. /** 
  16.  * @author lxn 
  17.  * @version Id: RSASignature.java, v 0.1 2016/7/21 16:14 lxn Exp $$ 
  18.  */  
  19. public class RSASignature {  
  20.   
  21.   
  22.   
  23.   
  24.     /** 
  25.      * 签名算法 
  26.      */  
  27.     public static final String SIGN_ALGORITHMS = "SHA1WithRSA";  
  28.   
  29.     /** 
  30.      * RSA签名 
  31.      * @param content 待签名数据 
  32.      * @param privateKey 商户私钥 
  33.      * @param encode 字符集编码 
  34.      * @return 签名值 
  35.      */  
  36.     public static String sign(String content, String privateKey, String encode)  
  37.     {  
  38.         try  
  39.         {  
  40.             PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );  
  41.   
  42.             KeyFactory keyf                 = KeyFactory.getInstance("RSA");  
  43.             PrivateKey priKey               = keyf.generatePrivate(priPKCS8);  
  44.   
  45.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);  
  46.   
  47.             signature.initSign(priKey);  
  48.             signature.update( content.getBytes(encode));  
  49.   
  50.             byte[] signed = signature.sign();  
  51.   
  52.             return Base64.encode(signed);  
  53.         }  
  54.         catch (Exception e)  
  55.         {  
  56.             e.printStackTrace();  
  57.         }  
  58.   
  59.         return null;  
  60.     }  
  61.   
  62.     public static String sign(String content, String privateKey)  
  63.     {  
  64.         try  
  65.         {  
  66.             PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );  
  67.             KeyFactory keyf = KeyFactory.getInstance("RSA");  
  68.             PrivateKey priKey = keyf.generatePrivate(priPKCS8);  
  69.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);  
  70.             signature.initSign(priKey);  
  71.             signature.update( content.getBytes());  
  72.             byte[] signed = signature.sign();  
  73.             return Base64.encode(signed);  
  74.         }  
  75.         catch (Exception e)  
  76.         {  
  77.             e.printStackTrace();  
  78.         }  
  79.         return null;  
  80.     }  
  81.   
  82.     /** 
  83.      * RSA验签名检查 
  84.      * @param content 待签名数据 
  85.      * @param sign 签名值 
  86.      * @param publicKey 分配给开发商公钥 
  87.      * @param encode 字符集编码 
  88.      * @return 布尔值 
  89.      */  
  90.     public static boolean doCheck(String content, String sign, String publicKey,String encode)  
  91.     {  
  92.         try  
  93.         {  
  94.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  95.             byte[] encodedKey = Base64.decode(publicKey);  
  96.             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));  
  97.   
  98.   
  99.             java.security.Signature signature = java.security.Signature  
  100.                     .getInstance(SIGN_ALGORITHMS);  
  101.   
  102.             signature.initVerify(pubKey);  
  103.             signature.update( content.getBytes(encode) );  
  104.   
  105.             boolean bverify = signature.verify( Base64.decode(sign) );  
  106.             return bverify;  
  107.   
  108.         }  
  109.         catch (Exception e)  
  110.         {  
  111.             e.printStackTrace();  
  112.         }  
  113.   
  114.         return false;  
  115.     }  
  116.   
  117.     public static boolean doCheck(String content, String sign, String publicKey)  
  118.     {  
  119.         try  
  120.         {  
  121.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  122.             byte[] encodedKey = Base64.decode(publicKey);  
  123.             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));  
  124.   
  125.   
  126.             java.security.Signature signature = java.security.Signature  
  127.                     .getInstance(SIGN_ALGORITHMS);  
  128.   
  129.             signature.initVerify(pubKey);  
  130.             signature.update( content.getBytes() );  
  131.   
  132.             boolean bverify = signature.verify( Base64.decode(sign) );  
  133.             return bverify;  
  134.   
  135.         }  
  136.         catch (Exception e)  
  137.         {  
  138.             e.printStackTrace();  
  139.         }  
  140.   
  141.         return false;  
  142.     }  
  143.   
  144. }  

BASE64:

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


版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/xiananliu/article/details/51996994
原文地址:https://www.cnblogs.com/amylis_chen/p/8616977.html