RSA加解密,双方各生成公私钥,并提供给对方公钥,对方用公钥加密数据,己方用保留的私钥进行解密

调用方式:

加密:encrypted=AuiRSA.rsaEncrypt(xml, auibPublicKey, charset_UTF8);
解密:AuiRSA.rsaDecrypt(encrypted, auibPrivateKey, charset_UTF8);    
 
public class AuiRSA {
     
     static final int EIGHTBIT = 8;
     
     static final int FOURBYTE = 4;
     
     static final int SIGN1 = -128;
     
     static final int SIXTEENBIT = 16;
     
     static final int CHUNK_SIZE = 76;    static final int BASELENGTH = 255;
    static final int LOOKUPLENGTH = 64;
     
     static final byte PAD = (byte) '=';    static final int TWENTYFOURBITGROUP = 24;
    static final String charset_UTF8="UTF-8";
     
     static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
     
     static String auibPublicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH1Rpgcs5Hd7P18n8eZAWKPmEWAuY2nQ33/iLmyEQw7hSeHTtsEUS4XYNnFz+dQDSZljOTytHp+b7YKw658t3Zhj45gir0UKkCxYdwyvbDuQwW3fOG76prseHfbvgpVCdfpD12d/IsZMIiSu4q5s2J4WvzJOLMMUradz6lBXABiQIDAQAB"; 
     
     static String auibPrivateKey="";     static String self_publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGvcSjtMQQM+iPjkcpk+0VG6VjiskbAr8fX1EZxRaAqOls9qZdzFDh9lQ0kcBqu2MCKtVFcvMC/GAfNBJsd0e3IO7JVx7K8FI3YnCr4h6l2NHrj3LxoU1Mb240klrmIFwh9u4mQb7gvo4HLQ0vQ0RJZOYKerxOSumuzYk4lNL6rQIDAQAB";
     
     static String self_privateKey="MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMa9xKO0xBAz6I+ORymT7RUbpWOKyRsCvx9fURnFFoCo6Wz2pl3MUOH2VDSRwGq7YwIq1UVy8wL8YB80Emx3R7cg7slXHsrwUjdicKviHqXY0euPcvGhTUxvbjSSWuYgXCH27iZBvuC+jgctDS9DRElk5gp6vE5K6a7NiTiU0vqtAgMBAAECgYEAhj1qFBWmlTcqr8SvppLngelxlkIJQrhhNiSg2CI6596wBMy5ZQP74hULnZKRgMZfwvgBpG5XXL3xg0Id66vKAOIqvVxW+F4LIS60kTHb8pwAbL14/FLd1WF2fTtWUSQKFAtaKUPcnl5c8tRvNlIzb+udRXx8c1n62FQ4/Jsx43UCQQD/Wb5dn44hrdNeam3rxWIZxslVI22mnLlG2GMUlmo/2EQzHxrIuF3X2ioQzkCgZIOdrMMmOcnwffvJzxRnFRdTAkEAxz8qrsz8sKRz92g5ugNNVb0w0yu5pa1r75f4rbHQNbFlYywS5G93n8/IiaTvirJINyp3sgu+r0rMKLbD1k9l/wJAKbWuC7rxS30KRqTZ2aY/NPiskFSeJ5X4CaN047sCFfWshjExfdHnukdvkZkvI0Pn38yFf+v2mWrqwvcpXQEr8wJBAJWOs5I8KhzJhIacRGB85ArMlR6dfp9++jsBHtf6VahH/SugxJmVlfxucj/nfyrjwdMu3GPX7w0THwYckgmG1a8CQQDzG8eSb8rifkaVU/hx9KfD21VC4f2RloLJ7Z1BjEw4E29IpDQdyF+28yuAQ8aIrc3bAFBHRfgM3UG9G7103hU5";    public static final String SIGN_TYPE        = "sign_type";
    public static final String SIGN_TYPE_RSA    = "RSA";
    public static final String SIGN_ALGORITHMS  = "SHA1WithRSA";
    public static final String SIGN             = "sign";
     
     public static final String ALIPAY_SDK       = "alipay_sdk";    public static final String CHARSET          = "charset";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_TIMEZONE    = "GMT+8";
    public static final String CHARSET_UTF8     = "UTF-8";
    public static final String CHARSET_GBK      = "GBK";
    private static final int MAX_ENCRYPT_BLOCK = 117;
    private static final int MAX_DECRYPT_BLOCK = 128;
    private static final int DEFAULT_BUFFER_SIZE = 8192;
     
     private static byte[] base64Alphabet = new byte[BASELENGTH];
      
     private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
         
     public static String getSignContent(Map<String, String> sortedParams) {
         StringBuffer content = new StringBuffer();
         List<String> keys = new ArrayList<String>(sortedParams.keySet());
         Collections.sort(keys);
         int index = 0;
         for (int i = 0; i < keys.size(); i++) {
             String key = keys.get(i);
             String value = sortedParams.get(key);
             if (AuiRSA.areNotEmpty(key, value)) {
                 content.append((index == 0 ? "" : "&") + key + "=" + value);
                 index++;
             }
         }
         return content.toString();
     }    public static String rsaSign(String content, String privateKey, String charset) throws Exception {
         try {
             PrivateKey priKey = getPrivateKeyFromPKCS8(AuiRSA.SIGN_TYPE_RSA,new ByteArrayInputStream(privateKey.getBytes()));
             java.security.Signature signature = java.security.Signature.getInstance(AuiRSA.SIGN_ALGORITHMS);
             signature.initSign(priKey);
             if (AuiRSA.isEmpty(charset)) {
                 signature.update(content.getBytes());
             } else {
                 signature.update(content.getBytes(charset));
             }
             byte[] signed = signature.sign();
             return new String(AuiRSA.encodeBase64(signed));
         } catch (Exception e) {
             throw new Exception("RSAcontent = " + content + "; charset = " + charset, e);
         }
     }    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
         if (ins == null || AuiRSA.isEmpty(algorithm)) {
             return null;
         }
         KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
         byte[] encodedKey = AuiRSA.readText(ins).getBytes();
         encodedKey = AuiRSA.decodeBase64(encodedKey);
         return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
     }    public static String getSignCheckContentV2(Map<String, String> params) {
         if (params == null) {
             return null;
         }
         params.remove("sign");
         StringBuffer content = new StringBuffer();
         List<String> keys = new ArrayList<String>(params.keySet());
         Collections.sort(keys);
         for (int i = 0; i < keys.size(); i++) {
             String key = keys.get(i);
             String value = params.get(key);
             content.append((i == 0 ? "" : "&") + key + "=" + value);
         }
         return content.toString();
     }    public static boolean rsaCheckContent(String content, String sign, String publicKey,String charset) throws Exception {
         try {
             PublicKey pubKey = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
             java.security.Signature signature = java.security.Signature.getInstance(AuiRSA.SIGN_ALGORITHMS);
             signature.initVerify(pubKey);
             if (AuiRSA.isEmpty(charset)) {
                 signature.update(content.getBytes());
             } else {
                 signature.update(content.getBytes(charset));
             }
             return signature.verify(AuiRSA.decodeBase64(sign.getBytes()));
         } catch (Exception e) {
             throw new Exception("RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
         }
     }    public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
         KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
         StringWriter writer = new StringWriter();
         AuiRSA.io(new InputStreamReader(ins), writer);
         byte[] encodedKey = writer.toString().getBytes();
         encodedKey = AuiRSA.decodeBase64(encodedKey);
         return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
     }    /**
      * 公钥加密
      * @param content   待加密内容
      * @param publicKey 公钥
      * @param charset   字符集,如UTF-8, GBK, GB2312
      * @return 密文内容
      * @throws AlipayApiException
      */
     public static String rsaEncrypt(String content, String publicKey, String charset) throws Exception {
         try {
             PublicKey pubKey = getPublicKeyFromX509(AuiRSA.SIGN_TYPE_RSA,new ByteArrayInputStream(publicKey.getBytes()));
             Cipher cipher = Cipher.getInstance(AuiRSA.SIGN_TYPE_RSA);
             cipher.init(Cipher.ENCRYPT_MODE, pubKey);
             byte[] data = AuiRSA.isEmpty(charset) ? content.getBytes() : content.getBytes(charset);
             int inputLen = data.length;
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             int offSet = 0;
             byte[] cache;
             int i = 0;
             // 对数据分段加密  
             while (inputLen - offSet > 0) {
                 if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                     cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                 } else {
                     cache = cipher.doFinal(data, offSet, inputLen - offSet);
                 }
                 out.write(cache, 0, cache.length);
                 i++;
                 offSet = i * MAX_ENCRYPT_BLOCK;
             }
             byte[] encryptedData = AuiRSA.encodeBase64(out.toByteArray());
             out.close();
             return AuiRSA.isEmpty(charset) ? new String(encryptedData) : new String(encryptedData, charset);
         } catch (Exception e) {
             throw new Exception("EncryptContent = " + content + ",charset = " + charset, e);
         }
     }    /**
      * 私钥解密
      * @param content    待解密内容
      * @param privateKey 私钥
      * @param charset    字符集,如UTF-8, GBK, GB2312
      * @return 明文内容
      * @throws AlipayApiException
      */
     public static String rsaDecrypt(String content, String privateKey, String charset) throws Exception {
         try {
             PrivateKey priKey = getPrivateKeyFromPKCS8(AuiRSA.SIGN_TYPE_RSA,new ByteArrayInputStream(privateKey.getBytes()));
             Cipher cipher = Cipher.getInstance(AuiRSA.SIGN_TYPE_RSA);
             cipher.init(Cipher.DECRYPT_MODE, priKey);
             byte[] encryptedData = AuiRSA.isEmpty(charset) ? AuiRSA.decodeBase64(content.getBytes()) : AuiRSA.decodeBase64(content.getBytes(charset));
             int inputLen = encryptedData.length;
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             int offSet = 0;
             byte[] cache;
             int i = 0;
             // 对数据分段解密  
             while (inputLen - offSet > 0) {
                 if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                     cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                 } else {
                     cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                 }
                 out.write(cache, 0, cache.length);
                 i++;
                 offSet = i * MAX_DECRYPT_BLOCK;
             }
             byte[] decryptedData = out.toByteArray();
             out.close();
             return AuiRSA.isEmpty(charset) ? new String(decryptedData) : new String(decryptedData, charset);
         } catch (Exception e) {
             throw new Exception("EncodeContent = " + content + ",charset = " + charset, e);
         }
     }    public static void io(InputStream in, OutputStream out) throws IOException {
         io(in, out, -1);
     }    public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {
         if (bufferSize == -1) {
             bufferSize = DEFAULT_BUFFER_SIZE;
         }
         byte[] buffer = new byte[bufferSize];
         int amount;
         while ((amount = in.read(buffer)) >= 0) {
             out.write(buffer, 0, amount);
         }
     }    public static void io(Reader in, Writer out) throws IOException {
         io(in, out, -1);
     }    public static void io(Reader in, Writer out, int bufferSize) throws IOException {
         if (bufferSize == -1) {
             bufferSize = DEFAULT_BUFFER_SIZE >> 1;
         }
         char[] buffer = new char[bufferSize];
         int amount;
         while ((amount = in.read(buffer)) >= 0) {
             out.write(buffer, 0, amount);
         }
     }    public static OutputStream synchronizedOutputStream(OutputStream out) {
         return new SynchronizedOutputStream(out);
     }    public static OutputStream synchronizedOutputStream(OutputStream out, Object lock) {
         return new SynchronizedOutputStream(out, lock);
     }    public static String readText(InputStream in) throws IOException {
         return readText(in, null, -1);
     }    public static String readText(InputStream in, String encoding) throws IOException {
         return readText(in, encoding, -1);
     }    public static String readText(InputStream in, String encoding, int bufferSize) throws IOException {
         Reader reader = (encoding == null) ? new InputStreamReader(in) : new InputStreamReader(in,encoding);
         return readText(reader, bufferSize);
     }    public static String readText(Reader reader) throws IOException {
         return readText(reader, -1);
     }    public static String readText(Reader reader, int bufferSize) throws IOException {
         StringWriter writer = new StringWriter();
         io(reader, writer, bufferSize);
         return writer.toString();
     }    private static class SynchronizedOutputStream extends OutputStream {
         private OutputStream out;
         private Object       lock;
         SynchronizedOutputStream(OutputStream out) {
             this(out, out);
         }
         SynchronizedOutputStream(OutputStream out, Object lock) {
             this.out = out;
             this.lock = lock;
         }
         public void write(int datum) throws IOException {
             synchronized (lock) {
                 out.write(datum);
             }
         }
         public void write(byte[] data) throws IOException {
             synchronized (lock) {
                 out.write(data);
             }
         }
         public void write(byte[] data, int offset, int length) throws IOException {
             synchronized (lock) {
                 out.write(data, offset, length);
             }
         }
         public void flush() throws IOException {
             synchronized (lock) {
                 out.flush();
             }
         }
         public void close() throws IOException {
             synchronized (lock) {
                 out.close();
             }
         }
     }    /**
      * 检查指定的字符串是否为空。
      * <ul>
      * <li>SysUtils.isEmpty(null) = true</li>
      * <li>SysUtils.isEmpty("") = true</li>
      * <li>SysUtils.isEmpty("   ") = true</li>
      * <li>SysUtils.isEmpty("abc") = false</li>
      * </ul>
      * @param value 待检查的字符串
      * @return true/false
      */
     public static boolean isEmpty(String value) {
         int strLen;
         if (value == null || (strLen = value.length()) == 0) {
             return true;
         }
         for (int i = 0; i < strLen; i++) {
             if ((Character.isWhitespace(value.charAt(i)) == false)) {
                 return false;
             }
         }
         return true;
     }    /**
      * 检查对象是否为数字型字符串,包含负数开头的。
      */
     public static boolean isNumeric(Object obj) {
         if (obj == null) {
             return false;
         }
         char[] chars = obj.toString().toCharArray();
         int length = chars.length;
         if(length < 1)
             return false;        int i = 0;
         if(length > 1 && chars[0] == '-')
             i = 1;
         
         for (; i < length; i++) {
             if (!Character.isDigit(chars[i])) {
                 return false;
             }
         }
         return true;
     }    /**
      * 检查指定的字符串列表是否不为空。
      */
     public static boolean areNotEmpty(String... values) {
         boolean result = true;
         if (values == null || values.length == 0) {
             result = false;
         } else {
             for (String value : values) {
                 result &= !isEmpty(value);
             }
         }
         return result;
     }    /**
      * 把通用字符编码的字符串转化为汉字编码。
      */
     public static String unicodeToChinese(String unicode) {
         StringBuilder out = new StringBuilder();
         if (!isEmpty(unicode)) {
             for (int i = 0; i < unicode.length(); i++) {
                 out.append(unicode.charAt(i));
             }
         }
         return out.toString();
     }    /**
      * 过滤不可见字符
      */
     public static String stripNonValidXMLCharacters(String input) {
         if (input == null || ("".equals(input)))
             return "";
         StringBuilder out = new StringBuilder();
         char current;
         for (int i = 0; i < input.length(); i++) {
             current = input.charAt(i);
             if ((current == 0x9) || (current == 0xA) || (current == 0xD)
                     || ((current >= 0x20) && (current <= 0xD7FF))
                     || ((current >= 0xE000) && (current <= 0xFFFD))
                     || ((current >= 0x10000) && (current <= 0x10FFFF)))
                 out.append(current);
         }
         return out.toString();
     }    
     /**
      * @Description: 取得唯一不重复的值
      * @return String
      */
     public static String getGuid() {
         return java.util.UUID.randomUUID().toString();
     }    /**  
      * @Description: MD5加密 
      * @param originstr
      * @return String 
      */
     public static String ecodeByMD5(String originstr) {
         String result = null;
         // 用来将字节转换成 16 进制表示的字�?
         char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };
         if (originstr != null) {
             try {
                 // 返回实现指定摘要算法�?MessageDigest 对象
                 MessageDigest md = MessageDigest.getInstance("MD5");
                 // 使用utf-8编码将originstr字符串编码并保存到source字节数组
                 byte[] source = originstr.getBytes("utf-8");
                 // 使用指定�?byte 数组更新摘要
                 md.update(source);
                 // 通过执行诸如填充之类的最终操作完成哈希计算,结果是一�?28位的长整�?
                 byte[] tmp = md.digest();
                 // �?6进制数表示需�?2�?
                 char[] str = new char[32];
                 for (int i = 0, j = 0; i < 16; i++) {
                     // j表示转换结果中对应的字符位置
                     // 从第�?��字节�?��,对 MD5 的每�?��字节
                     // 转换�?16 进制字符
                     byte b = tmp[i];
                     // 取字节中�?4 位的数字转换
                     // 无符号右移运算符>>> ,它总是在左边补0
                     // 0x代表它后面的是十六进制的数字. f转换成十进制就是15
                     str[j++] = hexDigits[b >>> 4 & 0xf];
                     // 取字节中�?4 位的数字转换
                     str[j++] = hexDigits[b & 0xf];
                 }
                 result = new String(str);// 结果转换成字符串用于返回
             } catch (NoSuchAlgorithmException e) {
                 // 当请求特定的加密算法而它在该环境中不可用时抛出此异常
                 e.printStackTrace();
             } catch (UnsupportedEncodingException e) {
                 // 不支持字符编码异�?
                 e.printStackTrace();
             }
         }
         return result;
     }
     /**
      * 按指定编码MD5加密 
      * @Description: 按指定编码MD5加密 
      * @param originstr 
      * @param encoding
      * @return String 
      */
     public static String ecodeByMD5(String originstr,String encoding) {
         String result = null;
         // 用来将字节转换成 16 进制表示的字�?
         char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };
         if (originstr != null) {
             try {
                 // 返回实现指定摘要算法�?MessageDigest 对象
                 MessageDigest md = MessageDigest.getInstance("MD5");
                 // 使用utf-8编码将originstr字符串编码并保存到source字节数组
                 if(encoding==null || encoding.trim().length()==0){
                     encoding="utf-8";
                 }
                 byte[] source = originstr.getBytes(encoding);
                 // 使用指定�?byte 数组更新摘要
                 md.update(source);
                 // 通过执行诸如填充之类的最终操作完成哈希计算,结果是一�?28位的长整�?
                 byte[] tmp = md.digest();
                 // �?6进制数表示需�?2�?
                 char[] str = new char[32];
                 for (int i = 0, j = 0; i < 16; i++) {
                     // j表示转换结果中对应的字符位置
                     // 从第�?��字节�?��,对 MD5 的每�?��字节
                     // 转换�?16 进制字符
                     byte b = tmp[i];
                     // 取字节中�?4 位的数字转换
                     // 无符号右移运算符>>> ,它总是在左边补0
                     // 0x代表它后面的是十六进制的数字. f转换成十进制就是15
                     str[j++] = hexDigits[b >>> 4 & 0xf];
                     // 取字节中�?4 位的数字转换
                     str[j++] = hexDigits[b & 0xf];
                 }
                 result = new String(str);// 结果转换成字符串用于返回
             } catch (NoSuchAlgorithmException e) {
                 // 当请求特定的加密算法而它在该环境中不可用时抛出此异常
                 e.printStackTrace();
             } catch (UnsupportedEncodingException e) {
                 // 不支持字符编码异�?
                 e.printStackTrace();
             }
         }
         return result;
     }    static {
         for (int i = 0; i < BASELENGTH; i++) {
             base64Alphabet[i] = (byte) -1;
         }
         for (int i = 'Z'; i >= 'A'; i--) {
             base64Alphabet[i] = (byte) (i - 'A');
         }
         for (int i = 'z'; i >= 'a'; i--) {
             base64Alphabet[i] = (byte) (i - 'a' + 26);
         }
         for (int i = '9'; i >= '0'; i--) {
             base64Alphabet[i] = (byte) (i - '0' + 52);
         }        base64Alphabet['+'] = 62;
         base64Alphabet['/'] = 63;        for (int i = 0; i <= 25; i++) {
             lookUpBase64Alphabet[i] = (byte) ('A' + i);
         }        for (int i = 26, j = 0; i <= 51; i++, j++) {
             lookUpBase64Alphabet[i] = (byte) ('a' + j);
         }        for (int i = 52, j = 0; i <= 61; i++, j++) {
             lookUpBase64Alphabet[i] = (byte) ('0' + j);
         }        lookUpBase64Alphabet[62] = (byte) '+';
         lookUpBase64Alphabet[63] = (byte) '/';
     }    private static boolean isBase64(byte octect) {
         if (octect == PAD) {
             return true;
         } else if (base64Alphabet[octect] == -1) {
             return false;
         } else {
             return true;
         }
     }    public static boolean isArrayByteBase64(byte[] arrayOctect) {
         arrayOctect = discardWhitespace(arrayOctect);
         int length = arrayOctect.length;
         if (length == 0) {
             return true;
         }
         for (int i = 0; i < length; i++) {
             if (!isBase64(arrayOctect[i])) {
                 return false;
             }
         }
         return true;
     }    public static byte[] encodeBase64(byte[] binaryData) {
         return encodeBase64(binaryData, false);
     }    public static byte[] encodeBase64Chunked(byte[] binaryData) {
         return encodeBase64(binaryData, true);
     }    public Object decode(Object pObject) throws Exception {
         if (!(pObject instanceof byte[])) {
             throw new Exception("Parameter supplied to Base64 decode is not a byte[]");
         }
         return decode((byte[]) pObject);
     }    public byte[] decode(byte[] pArray) {
         return decodeBase64(pArray);
     }    public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
         int lengthDataBits = binaryData.length * EIGHTBIT;
         int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
         int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
         byte encodedData[] = null;
         int encodedDataLength = 0;
         int nbrChunks = 0;
         if (fewerThan24bits != 0) {
             encodedDataLength = (numberTriplets + 1) * 4;
         } else {
             encodedDataLength = numberTriplets * 4;
         }
         if (isChunked) {
             nbrChunks = (CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE));
             encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
         }
         encodedData = new byte[encodedDataLength];
         byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
         int encodedIndex = 0;
         int dataIndex = 0;
         int i = 0;
         int nextSeparatorIndex = CHUNK_SIZE;
         int chunksSoFar = 0;
         for (i = 0; i < numberTriplets; i++) {
             dataIndex = i * 3;
             b1 = binaryData[dataIndex];
             b2 = binaryData[dataIndex + 1];
             b3 = binaryData[dataIndex + 2];
             l = (byte) (b2 & 0x0f);
             k = (byte) (b1 & 0x03);
             byte val1 = ((b1 & SIGN1) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
             byte val2 = ((b2 & SIGN1) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
             byte val3 = ((b3 & SIGN1) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2 | (k << 4)];
             encodedData[encodedIndex + 2] = lookUpBase64Alphabet[(l << 2) | val3];
             encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
             encodedIndex += 4;            if (isChunked) {
                 if (encodedIndex == nextSeparatorIndex) {
                     System.arraycopy(CHUNK_SEPARATOR,0,encodedData,encodedIndex,CHUNK_SEPARATOR.length);
                     chunksSoFar++;
                     nextSeparatorIndex = (CHUNK_SIZE * (chunksSoFar + 1)) + (chunksSoFar * CHUNK_SEPARATOR.length);
                     encodedIndex += CHUNK_SEPARATOR.length;
                 }
             }
         }        dataIndex = i * 3;
        if (fewerThan24bits == EIGHTBIT) {
             b1 = binaryData[dataIndex];
             k = (byte) (b1 & 0x03);
             byte val1 = ((b1 & SIGN1) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
             encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
             encodedData[encodedIndex + 2] = PAD;
             encodedData[encodedIndex + 3] = PAD;
         } else if (fewerThan24bits == SIXTEENBIT) {
             b1 = binaryData[dataIndex];
             b2 = binaryData[dataIndex + 1];
             l = (byte) (b2 & 0x0f);
             k = (byte) (b1 & 0x03);            byte val1 = ((b1 & SIGN1) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
             byte val2 = ((b2 & SIGN1) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2 | (k << 4)];
             encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
             encodedData[encodedIndex + 3] = PAD;
         }        if (isChunked) {
             if (chunksSoFar < nbrChunks) {
                 System.arraycopy(CHUNK_SEPARATOR,0,encodedData,encodedDataLength - CHUNK_SEPARATOR.length,CHUNK_SEPARATOR.length);
             }
         }
         return encodedData;
     }    public static byte[] decodeBase64(byte[] base64Data) {
         base64Data = discardNonBase64(base64Data);
         if (base64Data.length == 0) {
             return new byte[0];
         }
         int numberQuadruple = base64Data.length / FOURBYTE;
         byte decodedData[] = null;
         byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
         int encodedIndex = 0;
         int dataIndex = 0;
         {
             int lastData = base64Data.length;
             while (base64Data[lastData - 1] == PAD) {
                 if (--lastData == 0) {
                     return new byte[0];
                 }
             }
             decodedData = new byte[lastData - numberQuadruple];
         }
         
         for (int i = 0; i < numberQuadruple; i++) {
             dataIndex = i * 4;
             marker0 = base64Data[dataIndex + 2];
             marker1 = base64Data[dataIndex + 3];
             
             b1 = base64Alphabet[base64Data[dataIndex]];
             b2 = base64Alphabet[base64Data[dataIndex + 1]];
             
             if (marker0 != PAD && marker1 != PAD) {
                 b3 = base64Alphabet[marker0];
                 b4 = base64Alphabet[marker1];
                 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                 decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                 decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
             } else if (marker0 == PAD) {
                 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
             } else if (marker1 == PAD) {
                 b3 = base64Alphabet[marker0];
                 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                 decodedData[encodedIndex + 1] =  (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
             }
             encodedIndex += 3;
         }
         return decodedData;
     }
     
     static byte[] discardWhitespace(byte[] data) {
         byte groomedData[] = new byte[data.length];
         int bytesCopied = 0;
         
         for (int i = 0; i < data.length; i++) {
             switch (data[i]) {
             case (byte) ' ' :
             case (byte) '\n' :
             case (byte) '\r' :
             case (byte) '\t' :
                     break;
             default:
                     groomedData[bytesCopied++] = data[i];
             }
         }        byte packedData[] = new byte[bytesCopied];
        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
        return packedData;
     }    static byte[] discardNonBase64(byte[] data) {
         byte groomedData[] = new byte[data.length];
         int bytesCopied = 0;        for (int i = 0; i < data.length; i++) {
             if (isBase64(data[i])) {
                 groomedData[bytesCopied++] = data[i];
             }
         }
         byte packedData[] = new byte[bytesCopied];
         System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
         return packedData;
     }    public Object encode(Object pObject) throws Exception {
         if (!(pObject instanceof byte[])) {
             throw new Exception("Parameter supplied to Base64 encode is not a byte[]");
         }
         return encode((byte[]) pObject);
     }    public byte[] encode(byte[] pArray) {
         return encodeBase64(pArray, false);
     }    public String put(String key, Object value) {
         String strValue;
         if (value == null) {
             strValue = null;
         } else if (value instanceof String) {
             strValue = (String) value;
         } else if (value instanceof Integer) {
             strValue = ((Integer) value).toString();
         } else if (value instanceof Long) {
             strValue = ((Long) value).toString();
         } else if (value instanceof Float) {
             strValue = ((Float) value).toString();
         } else if (value instanceof Double) {
             strValue = ((Double) value).toString();
         } else if (value instanceof Boolean) {
             strValue = ((Boolean) value).toString();
         } else if (value instanceof Date) {
             DateFormat format = new SimpleDateFormat(AuiRSA.DATE_TIME_FORMAT);
             format.setTimeZone(TimeZone.getTimeZone(AuiRSA.DATE_TIMEZONE));
             strValue = format.format((Date) value);
         } else {
             strValue = value.toString();
         }
         return this.put(key, strValue);
     }
 }