参考了:
Java使用数字证书加密通信(加解密/加签验签)
https://www.cnblogs.com/shindo/p/6349070.html

http://snowolf.iteye.com/blog/391931
Java加密技术(八)——数字证书

http://snowolf.iteye.com/blog/735294
Java加密技术(十二)——.PFX(.p12)&个人信息交换文件

http://www.cnblogs.com/chnking/archive/2007/08/30/875947.html
使用X.509数字证书加密解密实务(二)-- 使用RSA证书加密敏感数据

证书组件工具类
CertificateCoder.java

package test;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Enumeration;

import javax.crypto.Cipher;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;  

/** 
 * 证书组件 
 *  
 * @author lijianbo
 * @version 1.0 
 * @since 1.0 
 */  
public abstract class CertificateCoder {  

    /** 
     * Java密钥�?Java Key Store,JKS)KEY_STORE 
     */  
    public static final String KEY_STORE = "PKCS12";  

    public static final String X509 = "X.509";  

    // rsa 加密方式
    public static final String  RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";

    /** 
     * 由KeyStore获得私钥 
     *  
     * @param strPfxPath 
     * @param strPassword 
     * @return 
     * @throws Exception 
     */  
    private static PrivateKey getPrivateKey(String strPfxPath, String strPassword) throws Exception {  
            try {  
                KeyStore ks = KeyStore.getInstance("PKCS12");  
                FileInputStream fis = new FileInputStream(strPfxPath);  
                // If the keystore password is empty(""), then we have to set  
                // to null, otherwise it won't work!!!  
                char[] nPassword = null;  
                if ((strPassword == null) || strPassword.trim().equals("")){  
                    nPassword = null;  
                }  
                else  
                {  
                    nPassword = strPassword.toCharArray();  
                }  
                ks.load(fis, nPassword);  
                fis.close();  
                System.out.println("keystore type=" + ks.getType());  
                // Now we loop all the aliases, we need the alias to get keys.  
                // It seems that this value is the "Friendly name" field in the  
                // detals tab <-- Certificate window <-- view <-- Certificate  
                // Button <-- Content tab <-- Internet Options <-- Tools menu   
                // In MS IE 6.  
                Enumeration enumas = ks.aliases();  
                String keyAlias = null;  
                if (enumas.hasMoreElements())// we are readin just one certificate.  
                {  
                    keyAlias = (String)enumas.nextElement();   
                    System.out.println("alias=[" + keyAlias + "]");  
                }  
                // Now once we know the alias, we could get the keys.  
                System.out.println("is key entry=" + ks.isKeyEntry(keyAlias));  
                PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);  
                Certificate cert = ks.getCertificate(keyAlias);  
                PublicKey pubkey = cert.getPublicKey();  
                System.out.println("cert class = " + cert.getClass().getName());  
                System.out.println("cert = " + cert);  
                System.out.println("public key = " + pubkey);  
                System.out.println("private key = " + prikey);  
                return prikey;  
            }  catch (Exception e) {  
                e.printStackTrace();  
            }  
            return null;  
    }  

    /** 
     * 由Certificate获得公钥 
     *  
     * @param certificatePath 
     * @return 
     * @throws Exception 
     */  
    private static PublicKey getPublicKey(String certificatePath)  
            throws Exception {  
        Certificate certificate = getCertificate(certificatePath);  
        PublicKey key = certificate.getPublicKey();  
        return key;  
    }  

    /** 
     * 获得Certificate 
     *  
     * @param certificatePath 
     * @return 
     * @throws Exception 
     */  
    private static Certificate getCertificate(String certificatePath)  
            throws Exception {  
        CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);  
        FileInputStream in = new FileInputStream(certificatePath);  

        Certificate certificate = certificateFactory.generateCertificate(in);  
        in.close();  

        return certificate;  
    }  

    /** 
     * 获得Certificate 
     *  
     * @param keyStorePath 
     * @param alias 
     * @param password 
     * @return 
     * @throws Exception 
     */  
    private static Certificate getCertificate(String keyStorePath,  
            String alias, String password) throws Exception {  
        KeyStore ks = getKeyStore(keyStorePath, password);  
        Certificate certificate = ks.getCertificate(alias);  

        return certificate;  
    }  

    /** 
     * 获得KeyStore 
     *  
     * @param keyStorePath 
     * @param password 
     * @return 
     * @throws Exception 
     */  
    private static KeyStore getKeyStore(String keyStorePath, String password)  
            throws Exception {  
        FileInputStream is = new FileInputStream(keyStorePath);  
        KeyStore ks = KeyStore.getInstance(KEY_STORE);  
        ks.load(is, password.toCharArray());  
        is.close();  
        return ks;  
    }  

    /** 
     * 私钥加密 
     *  
     * @param data 
     * @param keyStorePath 
     * @param alias 
     * @param password 
     * @return 
     * @throws Exception 
     */  
    public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String password) throws Exception {  
        // 取得私钥  
        PrivateKey privateKey = getPrivateKey(keyStorePath, password);  

        // 对数据加�? 
        Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());  
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);  

        return cipher.doFinal(data);  

    }  

    /** 
     * 私钥解密 
     *  
     * @param data 
     * @param keyStorePath 
     * @param alias 
     * @param password 
     * @return 
     * @throws Exception 
     */  
    public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath, String password) throws Exception {  
        // 取得私钥  
        PrivateKey privateKey = getPrivateKey(keyStorePath, password);  

        // 对数据加�? 
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);  
        cipher.init(Cipher.DECRYPT_MODE, privateKey);  

        return cipher.doFinal(data);  

    }  

    /** 
     * 公钥加密 
     *  
     * @param data 
     * @param certificatePath 
     * @return 
     * @throws Exception 
     */  
    public static byte[] encryptByPublicKey(byte[] data, String certificatePath)  
            throws Exception {  

        // 取得公钥  
        PublicKey publicKey = getPublicKey(certificatePath);  
        // 对数据加�? 
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);  
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);  

        return cipher.doFinal(data);  

    }  

    /** 
     * 公钥解密 
     *  
     * @param data 
     * @param certificatePath 
     * @return 
     * @throws Exception 
     */  
    public static byte[] decryptByPublicKey(byte[] data, String certificatePath)  
            throws Exception {  
        // 取得公钥  
        PublicKey publicKey = getPublicKey(certificatePath);  

        // 对数据加�? 
        Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());  
        cipher.init(Cipher.DECRYPT_MODE, publicKey);  

        return cipher.doFinal(data);  

    }  

    /** 
     * 验证Certificate 
     *  
     * @param certificatePath 
     * @return 
     */  
    public static boolean verifyCertificate(String certificatePath) {  
        return verifyCertificate(new Date(), certificatePath);  
    }  

    /** 
     * 验证Certificate是否过期或无�?
     *  
     * @param date 
     * @param certificatePath 
     * @return 
     */  
    public static boolean verifyCertificate(Date date, String certificatePath) {  
        boolean status = true;  
        try {  
            // 取得证书  
            Certificate certificate = getCertificate(certificatePath);  
            // 验证证书是否过期或无�? 
            status = verifyCertificate(date, certificate);  
        } catch (Exception e) {  
            status = false;  
        }  
        return status;  
    }  

    /** 
     * 验证证书是否过期或无�?
     *  
     * @param date 
     * @param certificate 
     * @return 
     */  
    private static boolean verifyCertificate(Date date, Certificate certificate) {  
        boolean status = true;  
        try {  
            X509Certificate x509Certificate = (X509Certificate) certificate;  
            x509Certificate.checkValidity(date);  
        } catch (Exception e) {  
            status = false;  
        }  
        return status;  
    }  

    /** 
     * 签名 
     *  
     * @param keyStorePath 
     * @param alias 
     * @param password 
     *  
     * @return 
     * @throws Exception 
     */  
    public static String sign(byte[] sign, String keyStorePath, String alias,  
            String password) throws Exception {  
        // 获得证书  
        X509Certificate x509Certificate = (X509Certificate) getCertificate(  
                keyStorePath, alias, password);  
        // 获取私钥  
        KeyStore ks = getKeyStore(keyStorePath, password);  
        // 取得私钥  
        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password  
                .toCharArray());  

        // 构建签名  
        Signature signature = Signature.getInstance(x509Certificate  
                .getSigAlgName());  
        signature.initSign(privateKey);  
        signature.update(sign);  
        return encryptBASE64(signature.sign());  
    }  

    /** 
     * 验证签名 
     *  
     * @param data 
     * @param sign 
     * @param certificatePath 
     * @return 
     * @throws Exception 
     */  
    public static boolean verify(byte[] data, String sign,  
            String certificatePath) throws Exception {  
        // 获得证书  
        X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);  
        // 获得公钥  
        PublicKey publicKey = x509Certificate.getPublicKey();  
        // 构建签名  
        Signature signature = Signature.getInstance(x509Certificate  
                .getSigAlgName());  
        signature.initVerify(publicKey);  
        signature.update(data);  

        return signature.verify(decryptBASE64(sign));  

    }  

    /** 
     * 验证Certificate 
     *  
     * @param keyStorePath 
     * @param alias 
     * @param password 
     * @return 
     */  
    public static boolean verifyCertificate(Date date, String keyStorePath,  
            String alias, String password) {  
        boolean status = true;  
        try {  
            Certificate certificate = getCertificate(keyStorePath, alias,  
                    password);  
            status = verifyCertificate(date, certificate);  
        } catch (Exception e) {  
            status = false;  
        }  
        return status;  
    }  

    /** 
     * 验证Certificate 
     *  
     * @param keyStorePath 
     * @param alias 
     * @param password 
     * @return 
     */  
    public static boolean verifyCertificate(String keyStorePath, String alias,  
            String password) {  
        return verifyCertificate(new Date(), keyStorePath, alias, password);  
    }  

    /** 
     * BASE64解密 
     *  
     * @param key 
     * @return 
     * @throws Exception 
     */  
    @SuppressWarnings("restriction")
    public static byte[] decryptBASE64(String key) throws Exception {  
        return (new BASE64Decoder()).decodeBuffer(key);  
    }  

    /** 
     * BASE64加密 
     *  
     * @param key 
     * @return 
     * @throws Exception 
     */  
    @SuppressWarnings("restriction")
    public static String encryptBASE64(byte[] key) throws Exception {  
        return (new BASE64Encoder()).encodeBuffer(key);  
    }  
} 

测试类:
加密、解密没问题,但是签名测试未通过,应该需要自己写代码了。

package test;

import static org.junit.Assert.*;  

import org.junit.Test;

import com.example.springbootzuulgatwayproxy.encryption.CertificateCoder;  

/** 
 *  
 * @author 梁栋 
 * @version 1.0 
 * @since 1.0 
 */  
public class CertificateCoderTest {  
    private String password = "123456";  
    private String certificatePath = "C:/Users/bbo/Desktop/noprivate.cer";  
    private String keyStorePath = "C:/Users/bbo/Desktop/MyTest.pfx";  
    private String alias = "www.zlex.org";

    @Test  
    public void test() throws Exception {  
        System.err.println("公钥加密——私钥解密");  
        String inputStr = "李建波";  
        byte[] data = inputStr.getBytes();  

        byte[] encrypt = CertificateCoder.encryptByPublicKey(data,  certificatePath);  

        byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt, keyStorePath, password);  
        String outputStr = new String(decrypt);  

        System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);  

        // 验证数据一致  
        assertArrayEquals(data, decrypt);  

        // 验证证书有效  
        assertTrue(CertificateCoder.verifyCertificate(certificatePath));  

    }  

    @Test  
    public void testSign() throws Exception {  
        System.err.println("私钥加密——公钥解密");  

        String inputStr = "sign";  
        byte[] data = inputStr.getBytes();  

        byte[] encodedData = CertificateCoder.encryptByPrivateKey(data,  
                keyStorePath,password);  

        byte[] decodedData = CertificateCoder.decryptByPublicKey(encodedData,  
                certificatePath);  

        String outputStr = new String(decodedData);  
        System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);  
        assertEquals(inputStr, outputStr);  

        System.err.println("私钥签名——公钥验证签名");  
        // 产生签名  
        String sign = CertificateCoder.sign(encodedData, alias ,keyStorePath,  password);  
        System.err.println("签名:\r" + sign);  

        // 验证签名  
        boolean status = CertificateCoder.verify(encodedData, sign,  
                certificatePath);  
        System.err.println("状态:\r" + status);  
        assertTrue(status);  

    }  
}  

获取pfx文件的私钥,并加密、解密测试:
测试通过,可以使用。

ReadPFX.java

package test;

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.util.Enumeration;

import javax.crypto.Cipher;
import javax.security.cert.X509Certificate;

public class ReadPFX {

    public static void main(String[] args) throws Exception {
        String certificatePath = "C:/Users/bbo/Desktop/noprivate.cer";
        String pfxString = "C:/Users/bbo/Desktop/MyTest.pfx";
        String password = "123456";
        String data = "李建波";
        String RSA_TYPE = "RSA/ECB/PKCS1Padding";

        // 获取私钥
        ReadPFX pfx = new ReadPFX();
        PrivateKey privateKey = pfx.GetPvkformPfx(pfxString, password);

        //获取公钥
        InputStream inStream = new FileInputStream(certificatePath);
        X509Certificate cert = X509Certificate.getInstance(inStream);
        inStream.close();
        PublicKey publicKey = cert.getPublicKey();

        //加密
        Cipher cipher = Cipher.getInstance(RSA_TYPE);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] b = data.getBytes();
        /** 执行加密操作 */
        byte[] b1 = cipher.doFinal(b);
        //Base64编码,也可以不用这一步
        String encryption = new String(Base64.encodeBase64(b1), "UTF-8");
        System.err.println("密文为:" + encryption);

        /*
         *  解密
         */
        /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
        Cipher cipher2 = Cipher.getInstance(RSA_TYPE);
        cipher2.init(Cipher.DECRYPT_MODE, privateKey);
        //base64解码
        byte[] b2 = Base64.decodeBase64(encryption.getBytes());
        /** 执行解密操作 */
        byte[] b3 = cipher2.doFinal(b2);
        String decryption = new String(b3);
        System.err.println("明文为:" + decryption);
    }

    public ReadPFX() {
    }

    // 转换成十六进制字符串
    public static String Byte2String(byte[] b) {
        String hs = "";
        String stmp = "";

        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1)
                hs = hs + "0" + stmp;
            else
                hs = hs + stmp;
            // if (n<b.length-1) hs=hs+":";
        }
        return hs.toUpperCase();
    }

    public static byte[] StringToByte(int number) {
        int temp = number;
        byte[] b = new byte[4];
        for (int i = b.length - 1; i > -1; i--) {
            b[i] = new Integer(temp & 0xff).byteValue();// 将最高位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return b;
    }

    public PrivateKey GetPvkformPfx(String strPfx, String strPassword) {
        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(strPfx);
            // If the keystore password is empty(""), then we have to set
            // to null, otherwise it won't work!!!
            char[] nPassword = null;
            if ((strPassword == null) || strPassword.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = strPassword.toCharArray();
            }
            ks.load(fis, nPassword);
            fis.close();
            System.out.println("keystore type=" + ks.getType());
            // Now we loop all the aliases, we need the alias to get keys.
            // It seems that this value is the "Friendly name" field in the
            // detals tab <-- Certificate window <-- view <-- Certificate
            // Button <-- Content tab <-- Internet Options <-- Tools menu
            // In MS IE 6.
            Enumeration enumas = ks.aliases();
            String keyAlias = null;
            if (enumas.hasMoreElements())// we are readin just one certificate.
            {
                keyAlias = (String) enumas.nextElement();
                System.out.println("alias=[" + keyAlias + "]");
            }
            // Now once we know the alias, we could get the keys.
            System.out.println("is key entry=" + ks.isKeyEntry(keyAlias));
            PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);
            Certificate cert = ks.getCertificate(keyAlias);
            PublicKey pubkey = cert.getPublicKey();
            System.out.println("cert class = " + cert.getClass().getName());
            System.out.println("cert = " + cert);
            System.out.println("public key = " + pubkey);
            System.out.println("private key = " + prikey);
            return prikey;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

Base64工具类:

package test;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 
 * 描述:Base64加密
 * 
 * @author yangyongchuan 2016年11月8日 上午10:28:17
 * @version 1.0
 */
public class Base64 {
    /**
     * Chunk size per RFC 2045 section 6.8.
     *
     * <p>
     * The {@value} character limit does not count the trailing CRLF, but counts
     * all other characters, including any equal signs.
     * </p>
     *
     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section
     *      6.8</a>
     */
    static final int      CHUNK_SIZE           = 76;

    /**
     * Chunk separator per RFC 2045 section 2.1.
     *
     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section
     *      2.1</a>
     */
    static final byte[]   CHUNK_SEPARATOR      = "\r\n".getBytes();

    /**
     * The base length.
     */
    static final int      BASELENGTH           = 255;

    /**
     * Lookup length.
     */
    static final int      LOOKUPLENGTH         = 64;

    /**
     * Used to calculate the number of bits in a byte.
     */
    static final int      EIGHTBIT             = 8;

    /**
     * Used when encoding something which has fewer than 24 bits.
     */
    static final int      SIXTEENBIT           = 16;

    /**
     * Used to determine how many bits data contains.
     */
    static final int      TWENTYFOURBITGROUP   = 24;

    /**
     * Used to get the number of Quadruples.
     */
    static final int      FOURBYTE             = 4;

    /**
     * Used to test the sign of a byte.
     */
    static final int      SIGN                 = -128;

    /**
     * Byte used to pad output.
     */
    static final byte     PAD                  = (byte) '=';

    // Create arrays to hold the base64 characters and a
    // lookup for base64 chars
    private static byte[] base64Alphabet       = new byte[BASELENGTH];
    private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];

    // Populating the lookup and character arrays
    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;
        }
    }

    /**
     * Tests a given byte array to see if it contains only valid characters
     * within the Base64 alphabet.
     *
     * @param arrayOctect
     *            byte array to test
     * @return true if all bytes are valid characters in the Base64 alphabet or
     *         if the byte array is empty; false, otherwise
     */
    public static boolean isArrayByteBase64(byte[] arrayOctect) {

        arrayOctect = discardWhitespace(arrayOctect);

        int length = arrayOctect.length;
        if (length == 0) {
            // shouldn't a 0 length array be valid base64 data?
            // return false;
            return true;
        }
        for (int i = 0; i < length; i++) {
            if (!isBase64(arrayOctect[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * Encodes binary data using the base64 algorithm but does not chunk the
     * output.
     *
     * @param binaryData
     *            binary data to encode
     * @return Base64 characters
     */
    public static byte[] encodeBase64(byte[] binaryData) {
        return encodeBase64(binaryData, false);
    }

    /**
     * Encodes binary data using the base64 algorithm and chunks the encoded
     * output into 76 character blocks
     *
     * @param binaryData
     *            binary data to encode
     * @return Base64 characters chunked in 76 character blocks
     */
    public static byte[] encodeBase64Chunked(byte[] binaryData) {
        return encodeBase64(binaryData, true);
    }

    /**
     * Decodes a byte[] containing containing characters in the Base64 alphabet.
     *
     * @param pArray
     *            A byte array containing Base64 character data
     * @return a byte array containing binary data
     */
    public static byte[] decode(byte[] pArray) {
        return decodeBase64(pArray);
    }

    /**
     * Encodes binary data using the base64 algorithm, optionally chunking the
     * output into 76 character blocks.
     *
     * @param binaryData
     *            Array containing binary data to encode.
     * @param isChunked
     *            if isChunked is true this encoder will chunk the base64 output
     *            into 76 character blocks
     * @return Base64-encoded data.
     */
    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) {
            // data not divisible by 24 bit
            encodedDataLength = (numberTriplets + 1) * 4;
        } else {
            // 16 or 8 bit
            encodedDataLength = numberTriplets * 4;
        }

        // If the output is to be "chunked" into 76 character sections,
        // for compliance with RFC 2045 MIME, then it is important to
        // allow for extra length to account for the separator(s)
        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 we are chunking, let's put a chunk separator down.
            if (isChunked) {
                // this assumes that CHUNK_SIZE % 4 == 0
                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;
                }
            }
        }

        // form integral number of 6-bit groups
        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) {
            // we also add a separator to the end of the final chunk.
            if (chunksSoFar < nbrChunks) {
                System.arraycopy(CHUNK_SEPARATOR, 0, encodedData, encodedDataLength - CHUNK_SEPARATOR.length, CHUNK_SEPARATOR.length);
            }
        }

        return encodedData;
    }

    /**
     * Decodes Base64 data into octects
     *
     * @param base64Data
     *            Byte array containing Base64 data
     * @return Array containing decoded data.
     */
    public static byte[] decodeBase64(byte[] base64Data) {
        // RFC 2045 requires that we discard ALL non-Base64 characters
        base64Data = discardNonBase64(base64Data);

        // handle the edge case, so we don't have to worry about it later
        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;

        // Throw away anything not in base64Data

        int encodedIndex = 0;
        int dataIndex = 0;
        {
            // this sizes the output array properly - rlw
            int lastData = base64Data.length;
            // ignore the '=' padding
            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) {
                // No PAD e.g 3cQl
                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) {
                // Two PAD e.g. 3c[Pad][Pad]
                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
            } else if (marker1 == PAD) {
                // One PAD e.g. 3cQ[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;
    }

    /**
     * Discards any whitespace from a base-64 encoded block.
     *
     * @param data
     *            The base-64 encoded data to discard the whitespace from.
     * @return The data, less whitespace (see RFC 2045).
     */
    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;
    }

    /**
     * Discards any characters outside of the base64 alphabet, per the
     * requirements on page 25 of RFC 2045 - "Any characters outside of the
     * base64 alphabet are to be ignored in base64 encoded data."
     *
     * @param data
     *            The base-64 encoded data to groom
     * @return The data, less non-base64 characters (see RFC 2045).
     */
    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;
    }

    /**
     * Encodes a byte[] containing binary data, into a byte[] containing
     * characters in the Base64 alphabet.
     *
     * @param pArray
     *            a byte array containing binary data
     * @return A byte array containing only Base64 character data
     */
    public static byte[] encode(byte[] pArray) {
        return encodeBase64(pArray, false);
    }

    public static String encode(String str) throws UnsupportedEncodingException {
        String baseStr = new String(encode(str.getBytes("UTF-8")));

        str = str.trim();
        byte value[];
        try {
            value = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            value = str.getBytes();
        }
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
        byte[] input = md.digest(value);        
        if (input == null)
            return null;
        StringBuffer output = new StringBuffer(input.length * 2);
        for (int i = 0; i < input.length; i++) {
            int current = input[i] & 0xff;
            if (current < 16)
                output.append("0");
            output.append(Integer.toString(current, 16));
        }
        String tempStr = output.toString().toUpperCase();
        String result = tempStr + baseStr;
        return new String(encode(result.getBytes("UTF-8")));
    }

    public static String decode(String cryptoStr) throws UnsupportedEncodingException {
        if (cryptoStr.length() < 40)
            return "";
        try {
            String tempStr = new String(decode(cryptoStr.getBytes("UTF-8")));
            String result = tempStr.substring(40, tempStr.length());
            return new String(decode(result.getBytes("UTF-8")));
        } catch (java.lang.ArrayIndexOutOfBoundsException ex) {
            return "";
        }
    }

    /**
     * Decodes Base64 data into octects
     *
     * @param encoded
     *            string containing Base64 data
     * @return Array containind decoded data.
     */
    public static byte[] decode2(String encoded) {

        if (encoded == null) {
            return null;
        }

        char[] base64Data = encoded.toCharArray();
        // remove white spaces
        int len = removeWhiteSpace(base64Data);

        if (len % FOURBYTE != 0) {
            return null;// should be divisible by four
        }

        int numberQuadruple = (len / FOURBYTE);

        if (numberQuadruple == 0) {
            return new byte[0];
        }

        byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;

        int i = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        decodedData = new byte[(numberQuadruple) * 3];

        for (; i < numberQuadruple - 1; i++) {

            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
                    || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) {
                return null;
            } // if found "no data" just return null

            b1 = base64Alphabet[d1];
            b2 = base64Alphabet[d2];
            b3 = base64Alphabet[d3];
            b4 = base64Alphabet[d4];

            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
        }

        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
            return null;// if found "no data" just return null
        }

        b1 = base64Alphabet[d1];
        b2 = base64Alphabet[d2];

        d3 = base64Data[dataIndex++];
        d4 = base64Data[dataIndex++];
        if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
            if (isPad(d3) && isPad(d4)) {
                if ((b2 & 0xf) != 0)// last 4 bits should be zero
                {
                    return null;
                }
                byte[] tmp = new byte[i * 3 + 1];
                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                return tmp;
            } else if (!isPad(d3) && isPad(d4)) {
                b3 = base64Alphabet[d3];
                if ((b3 & 0x3) != 0)// last 2 bits should be zero
                {
                    return null;
                }
                byte[] tmp = new byte[i * 3 + 2];
                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                return tmp;
            } else {
                return null;
            }
        } else { // No PAD e.g 3cQl
            b3 = base64Alphabet[d3];
            b4 = base64Alphabet[d4];
            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);

        }

        return decodedData;
    }

    private static boolean isWhiteSpace(char octect) {
        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
    }

    private static boolean isData(char octect) {
        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
    }

    private static boolean isPad(char octect) {
        return (octect == PAD);
    }

    /**
     * remove WhiteSpace from MIME containing encoded Base64 data.
     *
     * @param data
     *            the byte array of base64 data (with WS)
     * @return the new length
     */
    private static int removeWhiteSpace(char[] data) {
        if (data == null) {
            return 0;
        }

        // count characters that's not whitespace
        int newSize = 0;
        int len = data.length;
        for (int i = 0; i < len; i++) {
            if (!isWhiteSpace(data[i])) {
                data[newSize++] = data[i];
            }
        }
        return newSize;
    }
}

自己写的RSA加密:

package cn.sccl.common.encrypt;

/*
 * --------------------------------------------**********-----------------------
 * ---------------------
 * 
 * 该算法于1977年由美国麻省理工学院MIT(Massachusetts Institute of Technology)的Ronal Rivest,Adi
 * Shamir和Len
 * Adleman三位年轻教授提出,并以三人的姓氏Rivest,Shamir和Adlernan命名为RSA算法,是一个支持变长密钥的公共密钥算法,
 * 需要加密的文件快的长度也是可变的!
 * 
 * 所谓RSA加密算法,是世界上第一个非对称加密算法,也是数论的第一个实际应用。它的算法如下:
 * 
 * 1.找两个非常大的质数p和q(通常p和q都有155十进制位或都有512十进制位)并计算n=pq,k=(p-1)(q-1)。
 * 
 * 2.将明文编码成整数M,保证M不小于0但是小于n。
 * 
 * 3.任取一个整数e,保证e和k互质,而且e不小于0但是小于k。加密钥匙(称作公钥)是(e, n)。
 * 
 * 4.找到一个整数d,使得ed除以k的余数是1(只要e和n满足上面条件,d肯定存在)。解密钥匙(称作密钥)是(d, n)。
 * 
 * 加密过程: 加密后的编码C等于M的e次方除以n所得的余数。
 * 
 * 解密过程: 解密后的编码N等于C的d次方除以n所得的余数。
 * 
 * 只要e、d和n满足上面给定的条件。M等于N。
 * 
 * --------------------------------------------**********-----------------------
 * ---------------------
 */
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * 
 * 描述:RSA加密
 * 
 * @author yangyongchuan 2016年11月8日 上午10:16:44
 * @version 1.0
 */
public class RSA {
    /** 指定key的大小 */
    private static int          KEYSIZE       = 1024;
    // 字符集
    private final static String CHARACTER_SET = "UTF-8";
    // rsa 加密方式
    public static final String  RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";

    /**
     * 
     * 描述:RSA 生成公钥、私钥对
     * 
     * @return
     * @throws Exception
     * @author yangyongchuan 2016年11月8日 上午10:16:56
     * @version 1.0
     */
    public static Map<String, String> generateKeyPair() throws Exception {
        /** RSA算法要求有一个可信任的随机数源 */
        SecureRandom sr = new SecureRandom();
        /** 为RSA算法创建一个KeyPairGenerator对象 */
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
        kpg.initialize(KEYSIZE, sr);
        /** 生成密匙对 */
        KeyPair kp = kpg.generateKeyPair();
        /** 得到公钥 */
        Key publicKey = kp.getPublic();
        byte[] publicKeyBytes = publicKey.getEncoded();
        String pub = new String(Base64.encodeBase64(publicKeyBytes), CHARACTER_SET);
        /** 得到私钥 */
        Key privateKey = kp.getPrivate();
        byte[] privateKeyBytes = privateKey.getEncoded();
        String pri = new String(Base64.encodeBase64(privateKeyBytes), CHARACTER_SET);

        Map<String, String> map = new HashMap<String, String>();
        map.put("publicKey", pub);
        map.put("privateKey", pri);
        RSAPublicKey rsp = (RSAPublicKey) kp.getPublic();
        BigInteger bint = rsp.getModulus();
        byte[] b = bint.toByteArray();
        byte[] deBase64Value = Base64.encodeBase64(b);
        String retValue = new String(deBase64Value);
        map.put("modulus", retValue);
        return map;
    }

    /**
     * 
     * 描述:加密:公钥加密数据
     * 
     * @param source
     * @param publicKey
     * @return
     * @throws Exception
     * @author yangyongchuan 2016年11月8日 上午10:18:31
     * @version 1.0
     */
    public static String encrypt(String source, String publicKey) throws Exception {
        Key key = getPublicKey(publicKey);
        /** 得到Cipher对象来实现对源数据的RSA加密 */
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] b = source.getBytes();
        /** 执行加密操作 */
        byte[] b1 = cipher.doFinal(b);
        return new String(Base64.encodeBase64(b1), CHARACTER_SET);
    }

    /**
     * 
     * 描述:解密:私钥解密数据
     * 
     * @param cryptograph
     * @param privateKey
     * @return
     * @throws Exception
     * @author yangyongchuan 2016年11月8日 上午10:19:04
     * @version 1.0
     */
    public static String decrypt(String cryptograph, String privateKey) throws Exception {
        Key key = getPrivateKey(privateKey);
        /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] b1 = Base64.decodeBase64(cryptograph.getBytes());
        /** 执行解密操作 */
        byte[] b = cipher.doFinal(b1);
        return new String(b);
    }

    /**
     * 
     * 描述:得到公钥:密钥字符串(经过base64编码)
     * 
     * @param key
     * @return
     * @throws Exception
     * @author yangyongchuan 2016年11月8日 上午10:21:02
     * @version 1.0
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(key.getBytes()));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 
     * 描述: 得到私钥: 密钥字符串(经过base64编码)
     * 
     * @param key
     * @return
     * @throws Exception
     * @author yangyongchuan 2016年11月8日 上午10:21:30
     * @version 1.0
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(key.getBytes()));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    /**
     * 
     * 描述:生成签名
     * 
     * @param content
     * @param privateKey
     * @return
     * @author yangyongchuan 2016年11月8日 上午10:23:04
     * @version 1.0
     */
    public static String sign(String content, String privateKey) {
        try {
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey.getBytes()));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);

            Signature signature = Signature.getInstance("SHA1WithRSA");

            signature.initSign(priKey);
            signature.update(content.getBytes(CHARACTER_SET));

            byte[] signed = signature.sign();

            return new String(Base64.encodeBase64(signed));
        } catch (Exception e) {

        }

        return null;
    }

    /**
     * 
     * 描述:检查签名
     * 
     * @param content
     * @param sign
     * @param publicKey
     * @return
     * @author yangyongchuan 2016年11月8日 上午10:23:21
     * @version 1.0
     */
    public static boolean checkSign(String content, String sign, String publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] encodedKey = Base64.decode2(publicKey);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

            java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA");

            signature.initVerify(pubKey);
            signature.update(content.getBytes("utf-8"));

            boolean bverify = signature.verify(Base64.decode2(sign));
            return bverify;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

}