java实现RSA加解密

一.前言

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。

二.示例代码

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


import javax.crypto.Cipher;


/**
 * RSA加解密工具类
 * @author 丶晓权
 * 在Linux中使用openssl
 * 生成私钥:openssl genrsa -out rsa_private_key.pem 1024
 * 把RSA私钥转换成PKCS8格式:openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
 * 生成RSA公钥:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
 * 或使用程序中的方法生成密钥对
 * 
 */
public class SignatureUtil {


	/**
	 * 公钥加密
	 * @param content加密前内容
	 * @param publicKey公钥
	 * @param charset加密编码
	 * @return 返回加密后的数据
	 * @throws Exception
	 */
	public static String rsaEncrypt(String content, String publicKey, String charset) throws Exception {
		PublicKey pubKey = getPublicKeyFromX509(new ByteArrayInputStream(publicKey.getBytes()));
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		byte[] data = (charset==null||charset.isEmpty()) ? 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 > 117) {
				cache = cipher.doFinal(data, offSet, 117);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 117;
		}
		byte[] encryptedData = Base64.encodeBase64(out.toByteArray());
		out.close();
		return (charset==null||charset.isEmpty()) ? new String(encryptedData) : new String(encryptedData, charset);
	}


	/**
	 * 私钥解密
	 * @param content待解密字符串
	 * @param privateKey 私钥key
	 * @param charset 编码
	 * @return 返回的解密后信息
	 * @throws Exception 异常
	 */
    public static String rsaDecrypt(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes()));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            byte[] encryptedData = (charset==null||charset.isEmpty()) ? Base64.decodeBase64(content.getBytes()) 
            		: Base64.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 > 128) {
                    cache = cipher.doFinal(encryptedData, offSet, 128);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * 128;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return (charset==null||charset.isEmpty()) ? new String(decryptedData) : new String(decryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncodeContent = " + content + ",charset = " + charset, e);
        }
    }


    /**
     * RSA签名
     * @param content
     * @param privateKey
     * @param charset
     * @return
     * @throws Exception
     */
    public static String rsaSign(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes()));
            java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");
            signature.initSign(priKey);
            if (charset==null||charset.isEmpty()) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            byte[] signed = signature.sign();
            return new String(Base64.encodeBase64(signed));
        } catch (Exception e) {
            throw new Exception("RSAcontent = " + content + "; charset = " + charset, e);
        }
    }
    
    /**
     * 签名校验
     * @param content
     * @param sign
     * @param publicKey
     * @param charset
     * @return
     * @throws Exception
     */
    public static boolean rsaCheckContent(String content, String sign, String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509(new ByteArrayInputStream(publicKey.getBytes()));
            java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");
            signature.initVerify(pubKey);
            if (charset==null||charset.isEmpty()) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            throw new Exception("RSAcontent=" + content + ",sign=" + sign + ",charset=" + charset, e);
        }
    }
    
    /**
     * 获取公钥
     * @param algorithm
     * @param ins
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKeyFromX509(InputStream is) throws Exception {
    	  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
          StringWriter writer = new StringWriter();
          Reader in=new InputStreamReader(is);
          char[] buffer = new char[4096];
          int amount;
          while ((amount = in.read(buffer)) >= 0) {
        	  writer.write(buffer, 0, amount);
          }
          byte[] encodedKey = writer.toString().getBytes();
          encodedKey = Base64.decodeBase64(encodedKey);
          return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }
    
    /**
     * 获取私钥
     * @param algorithm
     * @param is
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKeyFromPKCS8(InputStream is) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        StringWriter writer = new StringWriter();
        Reader in=new InputStreamReader(is);
        char[] buffer = new char[4096];
        int amount;
        while ((amount = in.read(buffer)) >= 0) {
      	  writer.write(buffer, 0, amount);
        }
        byte[] encodedKey = writer.toString().getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }
    
    /**
     * 生成密钥
     * @return
     * @throws Exception
     */
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);
        return keyPairGen.generateKeyPair();
    }
    
    /**
     * 根据密钥对获取公钥
     * @param keyPair
     * @return
     * @throws UnsupportedEncodingException 
     */
    public static String getRSAPublicKey(KeyPair keyPair,String charset) throws UnsupportedEncodingException {
    	PublicKey publicKey = keyPair.getPublic();
    	byte[] encodeBase64 = Base64.encodeBase64(publicKey.getEncoded());
    	return (charset==null||charset.isEmpty()) ? new String(encodeBase64) : new String(encodeBase64, charset);
    }
    
    /**
     * 根据密钥对获取公钥
     * @param keyPair
     * @return
     * @throws UnsupportedEncodingException 
     */
    public static String getRSAPrivateKey(KeyPair keyPair,String charset) throws UnsupportedEncodingException {
    	PrivateKey privateKey = keyPair.getPrivate();
    	byte[] encodeBase64 = Base64.encodeBase64(privateKey.getEncoded());
    	return (charset==null||charset.isEmpty()) ? new String(encodeBase64) : new String(encodeBase64, charset);
    }
}
	/**
	 * 公钥加密
	 * @param content加密前内容
	 * @param publicKey公钥
	 * @param charset加密编码
	 * @return 返回加密后的数据
	 * @throws Exception
	 */
	public static String rsaEncrypt(String content, String publicKey, String charset) throws Exception {
		PublicKey pubKey = getPublicKeyFromX509(new ByteArrayInputStream(publicKey.getBytes()));
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		byte[] data = (charset==null||charset.isEmpty()) ? 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 > 117) {
				cache = cipher.doFinal(data, offSet, 117);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 117;
		}
		byte[] encryptedData = Base64.encodeBase64(out.toByteArray());
		out.close();
		return (charset==null||charset.isEmpty()) ? new String(encryptedData) : new String(encryptedData, charset);
	}


	/**
	 * 私钥解密
	 * @param content待解密字符串
	 * @param privateKey 私钥key
	 * @param charset 编码
	 * @return 返回的解密后信息
	 * @throws Exception 异常
	 */
    public static String rsaDecrypt(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes()));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            byte[] encryptedData = (charset==null||charset.isEmpty()) ? Base64.decodeBase64(content.getBytes()) 
            		: Base64.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 > 128) {
                    cache = cipher.doFinal(encryptedData, offSet, 128);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * 128;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return (charset==null||charset.isEmpty()) ? new String(decryptedData) : new String(decryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncodeContent = " + content + ",charset = " + charset, e);
        }
    }


    /**
     * RSA签名
     * @param content
     * @param privateKey
     * @param charset
     * @return
     * @throws Exception
     */
    public static String rsaSign(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes()));
            java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");
            signature.initSign(priKey);
            if (charset==null||charset.isEmpty()) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            byte[] signed = signature.sign();
            return new String(Base64.encodeBase64(signed));
        } catch (Exception e) {
            throw new Exception("RSAcontent = " + content + "; charset = " + charset, e);
        }
    }
    
    /**
     * 签名校验
     * @param content
     * @param sign
     * @param publicKey
     * @param charset
     * @return
     * @throws Exception
     */
    public static boolean rsaCheckContent(String content, String sign, String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509(new ByteArrayInputStream(publicKey.getBytes()));
            java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");
            signature.initVerify(pubKey);
            if (charset==null||charset.isEmpty()) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            throw new Exception("RSAcontent=" + content + ",sign=" + sign + ",charset=" + charset, e);
        }
    }
    
    /**
     * 获取公钥
     * @param algorithm
     * @param ins
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKeyFromX509(InputStream is) throws Exception {
    	  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
          StringWriter writer = new StringWriter();
          Reader in=new InputStreamReader(is);
          char[] buffer = new char[4096];
          int amount;
          while ((amount = in.read(buffer)) >= 0) {
        	  writer.write(buffer, 0, amount);
          }
          byte[] encodedKey = writer.toString().getBytes();
          encodedKey = Base64.decodeBase64(encodedKey);
          return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }
    
    /**
     * 获取私钥
     * @param algorithm
     * @param is
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKeyFromPKCS8(InputStream is) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        StringWriter writer = new StringWriter();
        Reader in=new InputStreamReader(is);
        char[] buffer = new char[4096];
        int amount;
        while ((amount = in.read(buffer)) >= 0) {
      	  writer.write(buffer, 0, amount);
        }
        byte[] encodedKey = writer.toString().getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }
    
    /**
     * 生成密钥
     * @return
     * @throws Exception
     */
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);
        return keyPairGen.generateKeyPair();
    }
    
    /**
     * 根据密钥对获取公钥
     * @param keyPair
     * @return
     * @throws UnsupportedEncodingException 
     */
    public static String getRSAPublicKey(KeyPair keyPair,String charset) throws UnsupportedEncodingException {
    	PublicKey publicKey = keyPair.getPublic();
    	byte[] encodeBase64 = Base64.encodeBase64(publicKey.getEncoded());
    	return (charset==null||charset.isEmpty()) ? new String(encodeBase64) : new String(encodeBase64, charset);
    }
    
    /**
     * 根据密钥对获取公钥
     * @param keyPair
     * @return
     * @throws UnsupportedEncodingException 
     */
    public static String getRSAPrivateKey(KeyPair keyPair,String charset) throws UnsupportedEncodingException {
    	PrivateKey privateKey = keyPair.getPrivate();
    	byte[] encodeBase64 = Base64.encodeBase64(privateKey.getEncoded());
    	return (charset==null||charset.isEmpty()) ? new String(encodeBase64) : new String(encodeBase64, charset);
    }
}

三.测试代码

KeyPair keyPair = SignatureUtil.generateKeyPair();
String privateKey=SignatureUtil.getRSAPrivateKey(keyPair, "utf-8");
String publicKey=SignatureUtil.getRSAPublicKey(keyPair, "utf-8");
String rsaEncrypt = SignatureUtil.rsaEncrypt("测试", publicKey, "UTF-8");//加密
System.out.println(rsaEncrypt);
String rsaEncrypt2 = SignatureUtil.rsaEncrypt("测试", publicKey, "GBK");//加密
System.out.println(rsaEncrypt2);
System.out.println(SignatureUtil.rsaDecrypt(rsaEncrypt, privateKey, "UTF-8"));//解密
System.out.println(SignatureUtil.rsaDecrypt(rsaEncrypt, privateKey, "GBK"));//测试错误解密
System.out.println(SignatureUtil.rsaDecrypt(rsaEncrypt2, privateKey, "GBK"));//解密

String rsaSign = SignatureUtil.rsaSign("测试", privateKey, "UTF-8");//加签
String rsaSign2 = SignatureUtil.rsaSign("测试", privateKey, "GBK");//加签
System.out.println(rsaSign);
System.out.println(rsaSign2);
System.out.println(SignatureUtil.rsaCheckContent("测试", rsaSign, publicKey, "UTF-8"));//验签
System.out.println(SignatureUtil.rsaCheckContent("测试", rsaSign, publicKey, "GBK"));//测试错误验签
System.out.println(SignatureUtil.rsaCheckContent("测试", rsaSign2, publicKey, "GBK"));//验签

四.运行结果

HO2vj3HrzvuWPdF3gW0aqFqD4Ye5BONUcBWwcPEcX02SzD/tyMqsJFcRD1MHYzhlVArRW9+URzUGOpgqCo5oABP5GKP618T1UabJyCzv5sHgADURtERJDF7AXV+ud/5UD8h4koDMCFOa8EVP2CJW4MOWEgiRkY/zJJ9d09XwWyA=
j7WKo6Qs1V+D2mq+eBkPJzlnyAH9crx9lSg0rS1/5lxbFQQN5n+XlD6g3JFBng1Y8M5gwJfALKIK2u+i43Ch0utbJF6XsILfKU5ILI2WBoTMbmHcxR+CGS3Tv+ueD5BtfqI1P1R0P1ayMbUDLeHWRcDFs+s3YI3vrB3ZIrXEnyk=
测试
娴嬭瘯
测试
lqi3ve6TO2yYs6rUEf6NuoTGDz6FbvL6XYxyYQbT1L18iSHNolJ+m71V8MYIenkEtVPl75KDs1UMrSTbxA/V5+2O1nWP4Iw+80Eg3536zvI4J1Od/6UVUOZzhubNctVpUXYD7LY4vncvAV/mGSpl6BRqW20HnP9MMVDek1YaF/8=
ozcUhv19xhp/FveSQiU6MbBrwrjJBuMp1SiPdRkm4HJD+24r3tOcoHJrawSN99E/EYIAHZlcDPbOkABcMYKRJyHCdc18aRDWO/Sbf5121EWnk2NMdRKOtkuqfEbmSxjTjS/gUmcHEJd8Al4vvtz1kUHF7OdexXn++E38cWdBdIM=
true
false
true

四.Base64工具类

public class Base64 {
	static final int CHUNK_SIZE = 76;
	static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
	static final int BASELENGTH = 255;
	static final int LOOKUPLENGTH = 64;
	static final int EIGHTBIT = 8;
	static final int SIXTEENBIT = 16;
	static final int TWENTYFOURBITGROUP = 24;
	static final int FOURBYTE = 4;
	static final int SIGN = -128;
	static final byte PAD = (byte) '=';
	private static byte[] base64Alphabet = new byte[BASELENGTH];
	private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
	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 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
			byte val3 = ((b3 & SIGN) == 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 & SIGN) == 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 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
			byte val2 = ((b2 & SIGN) == 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);
	}
}

猜你喜欢

转载自blog.csdn.net/u012722296/article/details/81038948