Android AES,RSA方式数据加密解密代码记录


class Base64Encoder extends FilterOutputStream {

    private static final char[] chars = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
            'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
            'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
            'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', '+', '/'
    };

    private int charCount;
    private int carryOver;

    /***
     * Constructs a new Base64 encoder that writes output to the given
     * OutputStream.
     *
     * @param out the output stream
     */
    public Base64Encoder(OutputStream out) {
        super(out);
    }

    /***
     * Writes the given byte to the output stream in an encoded form.
     *
     * @throws IOException if an I/O error occurs
     */
    public void write(int b) throws IOException {
        // Take 24-bits from three octets, translate into four encoded chars
        // Break lines at 76 chars
        // If necessary, pad with 0 bits on the right at the end
        // Use = signs as padding at the end to ensure encodedLength % 4 == 0

        // Remove the sign bit,
        // thanks to Christian Schweingruber 
        if (b < 0) {
            b += 256;
        }

        // First byte use first six bits, save last two bits
        if (charCount % 3 == 0) {
            int lookup = b >> 2;
            carryOver = b & 3;        // last two bits
            out.write(chars[lookup]);
        }
        // Second byte use previous two bits and first four new bits,
        // save last four bits
        else if (charCount % 3 == 1) {
            int lookup = ((carryOver << 4) + (b >> 4)) & 63;
            carryOver = b & 15;       // last four bits
            out.write(chars[lookup]);
        }
        // Third byte use previous four bits and first two new bits,
        // then use last six new bits
        else if (charCount % 3 == 2) {
            int lookup = ((carryOver << 2) + (b >> 6)) & 63;
            out.write(chars[lookup]);
            lookup = b & 63;          // last six bits
            out.write(chars[lookup]);
            carryOver = 0;
        }
        charCount++;

        // Add newline every 76 output chars (that's 57 input chars)
        if (charCount % 57 == 0) {
            out.write('\n');
        }
    }

    /***
     * Writes the given byte array to the output stream in an
     * encoded form.
     *
     * @param buf the data to be written
     * @param off the start offset of the data
     * @param len the length of the data
     * @throws IOException if an I/O error occurs
     */
    public void write(byte[] buf, int off, int len) throws IOException {
        // This could of course be optimized
        for (int i = 0; i < len; i++) {
            write(buf[off + i]);
        }
    }

    /***
     * Closes the stream, this MUST be called to ensure proper padding is
     * written to the end of the output stream.
     *
     * @throws IOException if an I/O error occurs
     */
    public void close() throws IOException {
        // Handle leftover bytes
        if (charCount % 3 == 1) {  // one leftover
            int lookup = (carryOver << 4) & 63;
            out.write(chars[lookup]);
            out.write('=');
            out.write('=');
        } else if (charCount % 3 == 2) {  // two leftovers
            int lookup = (carryOver << 2) & 63;
            out.write(chars[lookup]);
            out.write('=');
        }
        super.close();
    }

    /***
     * Returns the encoded form of the given unencoded string.  The encoder
     * uses the ISO-8859-1 (Latin-1) encoding to convert the string to bytes.
     * For greater control over the encoding, encode the string to bytes
     * yourself and use encode(byte[]).
     *
     * @param unencoded the string to encode
     * @return the encoded form of the unencoded string
     */
    public static String encode(String unencoded) {
        byte[] bytes = null;
        try {
            bytes = unencoded.getBytes("UTF-8");
        } catch (UnsupportedEncodingException ignored) {
        }
        return encode(bytes);
    }

    /***
     * Returns the encoded form of the given unencoded string.
     *
     * @param bytes the bytes to encode
     * @return the encoded form of the unencoded string
     */
    public static String encode(byte[] bytes) {
        ByteArrayOutputStream out =
                new ByteArrayOutputStream((int) (bytes.length * 1.37));
        Base64Encoder encodedOut = new Base64Encoder(out);

        try {
            encodedOut.write(bytes);
            encodedOut.close();

            return out.toString("UTF-8");
        } catch (IOException ignored) {
            return null;
        }
    }
}
class Base64Decoder extends FilterInputStream {

    private static final char[] chars = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
            'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
            'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
            'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', '+', '/'
    };

    // A mapping between char values and six-bit integers
    private static final int[] ints = new int[128];

    static {
        for (int i = 0; i < 64; i++) {
            ints[chars[i]] = i;
        }
    }

    private int charCount;
    private int carryOver;

    /***
     * Constructs a new Base64 decoder that reads input from the given
     * InputStream.
     *
     * @param in the input stream
     */
    public Base64Decoder(InputStream in) {
        super(in);
    }

    /***
     * Returns the next decoded character from the stream, or -1 if
     * end of stream was reached.
     *
     * @return the decoded character, or -1 if the end of the
     * input stream is reached
     * @throws IOException if an I/O error occurs
     */
    public int read() throws IOException {
        // Read the next non-whitespace character
        int x;
        do {
            x = in.read();
            if (x == -1) {
                return -1;
            }
        } while (Character.isWhitespace((char) x));
        charCount++;

        // The '=' sign is just padding
        if (x == '=') {
            return -1;  // effective end of stream
        }

        // Convert from raw form to 6-bit form
        x = ints[x];

        // Calculate which character we're decoding now
        int mode = (charCount - 1) % 4;

        // First char save all six bits, go for another
        if (mode == 0) {
            carryOver = x & 63;
            return read();
        }
        // Second char use previous six bits and first two new bits,
        // save last four bits
        else if (mode == 1) {
            int decoded = ((carryOver << 2) + (x >> 4)) & 255;
            carryOver = x & 15;
            return decoded;
        }
        // Third char use previous four bits and first four new bits,
        // save last two bits
        else if (mode == 2) {
            int decoded = ((carryOver << 4) + (x >> 2)) & 255;
            carryOver = x & 3;
            return decoded;
        }
        // Fourth char use previous two bits and all six new bits
        else if (mode == 3) {
            int decoded = ((carryOver << 6) + x) & 255;
            return decoded;
        }
        return -1;  // can't actually reach this line
    }

    /***
     * Reads decoded data into an array of bytes and returns the actual
     * number of bytes read, or -1 if end of stream was reached.
     *
     * @param buf the buffer into which the data is read
     * @param off the start offset of the data
     * @param len the maximum number of bytes to read
     * @return the actual number of bytes read, or -1 if the end of the
     * input stream is reached
     * @throws IOException if an I/O error occurs
     */
    public int read(byte[] buf, int off, int len) throws IOException {
        if (buf.length < (len + off - 1)) {
            throw new IOException("The input buffer is too small: " + len +
                    " bytes requested starting at offset " + off + " while the buffer " +
                    " is only " + buf.length + " bytes long.");
        }

        // This could of course be optimized
        int i;
        for (i = 0; i < len; i++) {
            int x = read();
            if (x == -1 && i == 0) {  // an immediate -1 returns -1
                return -1;
            } else if (x == -1) {       // a later -1 returns the chars read so far
                break;
            }
            buf[off + i] = (byte) x;
        }
        return i;
    }

    /***
     * Returns the decoded form of the given encoded string, as a String.
     * Note that not all binary data can be represented as a String, so this
     * method should only be used for encoded String data.  Use decodeToBytes()
     * otherwise.
     *
     * @param encoded the string to decode
     * @return the decoded form of the encoded string
     */
    public static String decode(String encoded) {
        return new String(decodeToBytes(encoded));
    }

    /***
     * Returns the decoded form of the given encoded string, as bytes.
     *
     * @param encoded the string to decode
     * @return the decoded form of the encoded string
     */
    public static byte[] decodeToBytes(String encoded) {
        byte[] bytes = null;
        try {
            bytes = encoded.getBytes("UTF-8");
        } catch (UnsupportedEncodingException ignored) {
        }

        Base64Decoder in = new Base64Decoder(
                new ByteArrayInputStream(bytes));

        ByteArrayOutputStream out =
                new ByteArrayOutputStream((int) (bytes.length * 0.67));

        try {
            byte[] buf = new byte[4 * 1024];  // 4K buffer
            int bytesRead;
            while ((bytesRead = in.read(buf)) != -1) {
                out.write(buf, 0, bytesRead);
            }
            out.close();

            return out.toByteArray();
        } catch (IOException ignored) {
            return null;
        }
    }
}


package com.example;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * http://www.cnblogs.com/whoislcj/p/5473030.html
*
 * 什么是aes加密?
 * 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
 * 
*/ public class AESUtils { private final static String HEX = "0123456789ABCDEF"; private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";//AES是加密方式 CBC是工作模式 PKCS5Padding是填充模式 private static final String AES = "AES";//AES 加密 private static final String SHA1PRNG = "SHA1PRNG";//// SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法 /* * 生成随机数,可以当做动态的密钥 加密和解密的密钥必须一致,不然将不能解密 */ public static String generateKey() { try { SecureRandom localSecureRandom = SecureRandom.getInstance(SHA1PRNG); byte[] bytes_key = new byte[20]; localSecureRandom.nextBytes(bytes_key); String str_key = toHex(bytes_key); return str_key; } catch (Exception e) { e.printStackTrace(); } return null; } // 对密钥进行处理 private static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance(AES); //for android SecureRandom sr = null; // 在4.2以上版本中,SecureRandom获取方式发生了改变 // if (android.os.Build.VERSION.SDK_INT >= 17) { // sr = SecureRandom.getInstance(SHA1PRNG, "Crypto"); // } else { // sr = SecureRandom.getInstance(SHA1PRNG); // } // for Java sr = SecureRandom.getInstance(SHA1PRNG); sr.setSeed(seed); kgen.init(128, sr); //256 bits or 128 bits,192bits //AES中128位密钥版本有10个加密循环,192比特密钥版本有12个加密循环,256比特密钥版本则有14个加密循环。 SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw; } /* * 加密 */ public static String encrypt(String key, String cleartext) { if ("".equals(cleartext)) { return cleartext; } try { byte[] result = encrypt(key, cleartext.getBytes()); return Base64Encoder.encode(result); } catch (Exception e) { e.printStackTrace(); } return null; } /* * 加密 */ private static byte[] encrypt(String key, byte[] clear) throws Exception { byte[] raw = getRawKey(key.getBytes()); SecretKeySpec skeySpec = new SecretKeySpec(raw, AES); Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] encrypted = cipher.doFinal(clear); return encrypted; } /* * 解密 */ public static String decrypt(String key, String encrypted) { if ("".equals(encrypted)) { return encrypted; } try { byte[] enc = Base64Decoder.decodeToBytes(encrypted); byte[] result = decrypt(key, enc); return new String(result); } catch (Exception e) { e.printStackTrace(); } return null; } /* * 解密 */ private static byte[] decrypt(String key, byte[] encrypted) throws Exception { byte[] raw = getRawKey(key.getBytes()); SecretKeySpec skeySpec = new SecretKeySpec(raw, AES); Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING); cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] decrypted = cipher.doFinal(encrypted); return decrypted; } //二进制转字符 public static String toHex(byte[] buf) { if (buf == null) return ""; StringBuffer result = new StringBuffer(2 * buf.length); for (int i = 0; i < buf.length; i++) { appendHex(result, buf[i]); } return result.toString(); } private static void appendHex(StringBuffer sb, byte b) { sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); } public static void main(String[] args) { String jsonData = "abcdefghijklmnopqrstuvwxyz"; System.out.println("AESUtils jsonData ---->" + jsonData); System.out.println("AESUtils jsonData length ---->" + jsonData.length()); //生成key String secretKey = AESUtils.generateKey(); System.out.println("AESUtils secretKey ---->" + secretKey); //AES加密 long start = System.currentTimeMillis(); String encryStr = AESUtils.encrypt(secretKey, jsonData); long end = System.currentTimeMillis(); System.out.println("AESUtils encrypt cost time---->" + (end - start)); System.out.println("AESUtils jsonData(encrypted) ---->" + encryStr); System.out.println("AESUtils jsonData(encrypted) length ---->" + encryStr.length()); //AES解密 start = System.currentTimeMillis(); String decryStr = AESUtils.decrypt(secretKey, encryStr); end = System.currentTimeMillis(); System.out.println("AESUtils decrypt cost time---->" + (end - start)); System.out.println("AESUtils jsonData(decrypted) ---->" + decryStr); } }

AES->Android使用注意版本区别

运行结果

AESUtils jsonData ---->abcdefghijklmnopqrstuvwxyz
AESUtils jsonData length ---->26
AESUtils secretKey ---->90588CB299AEDF3F93CA6E023D5548C7B14F0028
AESUtils encrypt cost time---->235
AESUtils jsonData(encrypted) ---->CxX5KAOTuALTw+GvN3lWEu047ST5703NrlYYuofWV4A=
AESUtils jsonData(encrypted) length ---->44
AESUtils decrypt cost time---->0
AESUtils jsonData(decrypted) ---->abcdefghijklmnopqrstuvwxyz


package com.example;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;

/**
 * http://www.cnblogs.com/whoislcj/p/5470095.html 
*

*

 *     RSA算法是最流行的公钥密码算法,使用长度可以变化的密钥。RSA是第一个既能用于数据加密也能用于数字签名的算法。
 *
 * RSA算法原理如下:
 *
 * 1.随机选择两个大质数p和q,p不等于q,计算N=pq;
 * 2.选择一个大于1小于N的自然数e,e必须与(p-1)(q-1)互素。
 * 3.用公式计算出d:d×e = 1 (mod (p-1)(q-1)) 。
 * 4.销毁p和q。
 *
 * 最终得到的N和e就是“公钥”,d就是“私钥”,发送方使用N去加密数据,接收方只有使用d才能解开数据内容。
 *
 * RSA的安全性依赖于大数分解,小于1024位的N已经被证明是不安全的,而且由于RSA算法进行的都是大数计算,使得RSA最快的情况也比DES慢上倍,这是RSA最大的缺陷,因此通常只能用于加密少量数据或者加密密钥,但RSA仍然不失为一种高强度的算法。
 * 
*/ public class RSAUtils { public static final String RSA = "RSA";// 非对称加密密钥算法 public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式 public static final int DEFAULT_KEY_SIZE = 2048;//秘钥默认长度 public static final byte[] DEFAULT_SPLIT = "#PART#".getBytes(); // 当要加密的内容超过bufferSize,则采用partSplit进行分块加密 public static final int DEFAULT_BUFFERSIZE = (DEFAULT_KEY_SIZE / 8) - 11;// 当前秘钥支持加密的最大字节数 /** * 随机生成RSA密钥对 * * @param keyLength 密钥长度,范围:512~2048 * 一般1024 * @return */ public static KeyPair generateRSAKeyPair(int keyLength) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA); kpg.initialize(keyLength); return kpg.genKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * 用公钥对字符串进行加密 * * @param data 原文 */ public static byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception { // 得到公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(RSA); PublicKey keyPublic = kf.generatePublic(keySpec); // 加密数据 Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.ENCRYPT_MODE, keyPublic); return cp.doFinal(data); } /** * 私钥加密 * * @param data 待加密数据 * @param privateKey 密钥 * @return byte[] 加密数据 */ public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception { // 得到私钥 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf = KeyFactory.getInstance(RSA); PrivateKey keyPrivate = kf.generatePrivate(keySpec); // 数据加密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.ENCRYPT_MODE, keyPrivate); return cipher.doFinal(data); } /** * 公钥解密 * * @param data 待解密数据 * @param publicKey 密钥 * @return byte[] 解密数据 */ public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception { // 得到公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(RSA); PublicKey keyPublic = kf.generatePublic(keySpec); // 数据解密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.DECRYPT_MODE, keyPublic); return cipher.doFinal(data); } /** * 使用私钥进行解密 */ public static byte[] decryptByPrivateKey(byte[] encrypted, byte[] privateKey) throws Exception { // 得到私钥 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf = KeyFactory.getInstance(RSA); PrivateKey keyPrivate = kf.generatePrivate(keySpec); // 解密数据 Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.DECRYPT_MODE, keyPrivate); byte[] arr = cp.doFinal(encrypted); return arr; } /** * 用公钥对字符串进行分段加密 */ public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception { int dataLen = data.length; if (dataLen <= DEFAULT_BUFFERSIZE) { return encryptByPublicKey(data, publicKey); } List allBytes = new ArrayList(2048); int bufIndex = 0; int subDataLoop = 0; byte[] buf = new byte[DEFAULT_BUFFERSIZE]; for (int i = 0; i < dataLen; i++) { buf[bufIndex] = data[i]; if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) { subDataLoop++; if (subDataLoop != 1) { for (byte b : DEFAULT_SPLIT) { allBytes.add(b); } } byte[] encryptBytes = encryptByPublicKey(buf, publicKey); for (byte b : encryptBytes) { allBytes.add(b); } bufIndex = 0; if (i == dataLen - 1) { buf = null; } else { buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)]; } } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 分段加密 * * @param data 要加密的原始数据 * @param privateKey 秘钥 */ public static byte[] encryptByPrivateKeyForSpilt(byte[] data, byte[] privateKey) throws Exception { int dataLen = data.length; if (dataLen <= DEFAULT_BUFFERSIZE) { return encryptByPrivateKey(data, privateKey); } List allBytes = new ArrayList(2048); int bufIndex = 0; int subDataLoop = 0; byte[] buf = new byte[DEFAULT_BUFFERSIZE]; for (int i = 0; i < dataLen; i++) { buf[bufIndex] = data[i]; if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) { subDataLoop++; if (subDataLoop != 1) { for (byte b : DEFAULT_SPLIT) { allBytes.add(b); } } byte[] encryptBytes = encryptByPrivateKey(buf, privateKey); for (byte b : encryptBytes) { allBytes.add(b); } bufIndex = 0; if (i == dataLen - 1) { buf = null; } else { buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)]; } } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 公钥分段解密 * * @param encrypted 待解密数据 * @param publicKey 密钥 */ public static byte[] decryptByPublicKeyForSpilt(byte[] encrypted, byte[] publicKey) throws Exception { int splitLen = DEFAULT_SPLIT.length; if (splitLen <= 0) { return decryptByPublicKey(encrypted, publicKey); } int dataLen = encrypted.length; List allBytes = new ArrayList(1024); int latestStartIndex = 0; for (int i = 0; i < dataLen; i++) { byte bt = encrypted[i]; boolean isMatchSplit = false; if (i == dataLen - 1) { // 到data的最后了 byte[] part = new byte[dataLen - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPublicKey(part, publicKey); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } else if (bt == DEFAULT_SPLIT[0]) { // 这个是以split[0]开头 if (splitLen > 1) { if (i + splitLen < dataLen) { // 没有超出data的范围 for (int j = 1; j < splitLen; j++) { if (DEFAULT_SPLIT[j] != encrypted[i + j]) { break; } if (j == splitLen - 1) { // 验证到split的最后一位,都没有break,则表明已经确认是split段 isMatchSplit = true; } } } } else { // split只有一位,则已经匹配了 isMatchSplit = true; } } if (isMatchSplit) { byte[] part = new byte[i - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPublicKey(part, publicKey); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 使用私钥分段解密 */ public static byte[] decryptByPrivateKeyForSpilt(byte[] encrypted, byte[] privateKey) throws Exception { int splitLen = DEFAULT_SPLIT.length; if (splitLen <= 0) { return decryptByPrivateKey(encrypted, privateKey); } int dataLen = encrypted.length; List allBytes = new ArrayList(1024); int latestStartIndex = 0; for (int i = 0; i < dataLen; i++) { byte bt = encrypted[i]; boolean isMatchSplit = false; if (i == dataLen - 1) { // 到data的最后了 byte[] part = new byte[dataLen - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPrivateKey(part, privateKey); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } else if (bt == DEFAULT_SPLIT[0]) { // 这个是以split[0]开头 if (splitLen > 1) { if (i + splitLen < dataLen) { // 没有超出data的范围 for (int j = 1; j < splitLen; j++) { if (DEFAULT_SPLIT[j] != encrypted[i + j]) { break; } if (j == splitLen - 1) { // 验证到split的最后一位,都没有break,则表明已经确认是split段 isMatchSplit = true; } } } } else { // split只有一位,则已经匹配了 isMatchSplit = true; } } if (isMatchSplit) { byte[] part = new byte[i - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPrivateKey(part, privateKey); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj9O5dd2u4JWV6ca/Vn9Q7x4Y0nSqzOPq\n" + "tqYc3H3e2Ld7+1yInU4HsuYlg1uvgRr7msztyI0jRY9iZaIYhL3aPenbA9PnyxiAw1s7Pl8NwjFe\n" + "5fT2uLynu4wkrqA5sLMHVt/L2grAcp9C14Eo5CVuXtUk7JEqfVQoQ2SWj1N89Oe/Ubtgbv0j2Bdr\n" + "DwdW8+l+qIXA7AKRBh+HcdpHxnkVZDKfzBMNea7KjfFrqUvC6Q4GjbXG65sQ4rI/gX0iOD0BGlsF\n" + "0MKBLkbCmAW4DP6QaMsqbgsO3aMCvVHcn6MQvmPbfFA5uH1uMRhydr+m2XvggUS6YHm1tfCoYvby\n" + "BTcMMwIDAQAB"; public static final String PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCP07l13a7glZXpxr9Wf1DvHhjS\n" + "dKrM4+q2phzcfd7Yt3v7XIidTgey5iWDW6+BGvuazO3IjSNFj2JlohiEvdo96dsD0+fLGIDDWzs+\n" + "Xw3CMV7l9Pa4vKe7jCSuoDmwswdW38vaCsByn0LXgSjkJW5e1STskSp9VChDZJaPU3z0579Ru2Bu\n" + "/SPYF2sPB1bz6X6ohcDsApEGH4dx2kfGeRVkMp/MEw15rsqN8WupS8LpDgaNtcbrmxDisj+BfSI4\n" + "PQEaWwXQwoEuRsKYBbgM/pBoyypuCw7dowK9UdyfoxC+Y9t8UDm4fW4xGHJ2v6bZe+CBRLpgebW1\n" + "8Khi9vIFNwwzAgMBAAECggEARRF3zpJWmKM9CrbWy8L4KtxZLze3jg0lefDrizcm/QugDmWxdVkz\n" + "eUXsXdh5v5YlnYEr71NXzN++cPAWtig11eWnt37boTxzGV2GZb1f7hGncObiVHTEV9xFAVcQXTqc\n" + "G6v9SQhAwsqYXsU3zdfr2L6irLhJn0X6z+JOKyX8q96h1eZJVvGm0bQQTtIDAVHi0YpHt2rw/XBK\n" + "u4hYaLl8mxUU1e9g/HX6wz7GfzJSgIhMt0xbpJ19os0FT9Zh0OKgcUsN54D2Bf/ZGg/G2+QHRZX6\n" + "EE6bM7taThYtYi6wEAHaG0SsuUEfDtFLlGv5U5Xer1YvDoyRS9SRQJbtNDArAQKBgQDu3njuXprb\n" + "O16A8A1msuF+ncHBFBsdfxR/EUue+K25zyAwFMHS0GglfDX1nib09G47TbWbCflb35WSstHIfh09\n" + "anhneBk09NpMqZAaNaEtujBYV62VloD5EzWW8ZyEzghCUs9//76tyyl3BD0c2eblpeFqSsK3PE68\n" + "mNtOe4RkyQKBgQCaJFL7AGqhmxJwijLtn70huO0uSs17ye2u3qUkkL1je/CZRg4ESx9pYv8wTQ6J\n" + "FZgB6kozjVobkOLS1f4cXlWBJlskP0qzX+ZJNdaRpITLX14LbmeIGHyi5sFWAqdCrS+oBbjiWDF5\n" + "VpLA1Z7t9IalLXirijt8Qmb87U+3OtmTGwKBgEcxnZ+GKOeAqWkKoyPh2t2PDWmLoY1IDAbXU8+c\n" + "1MKVnkVWWnKH1RKfE8ISEhBeLeCVB7Se42hjmkPv8iCsnfBpJFvKatDizZGd1CpLo69qV/BsqXr1\n" + "MZmLBSTo/DqE4edKoTfINL+91qz3YXOQ6oW1zBqPD7vnSJxjfrHElLApAoGAUx+vmChbWJcV1JbS\n" + "bA6uodbmIQa51T3J7XmnuRZM669UynNa77nLULvQPi3v3sFEXhQIu9BIfYEesPAxvv6oQaN7lwqC\n" + "sETRHT3pXlVIP5xITQXW0y/RVs/2BvobVPusLYIYeAdzdqnXLiKFOHGbgswIvQkolxQAEfmv+XHF\n" + "D20CgYAcKij5wyvIAdCR7uDagIRYL4NFkuOFUPRrdh7mz+pw/aDhPGWbGTAl7VPPk1ixJA5vweuf\n" + "awOyoe4gZKGXVx8wqJhvUeL8ExgE45IX8xIjmBXBZEgGY4xlqBM5qFgP0jqKi4zPPNP9I0ga1sCQ\n" + "dj2rH2JUe8VW5tnfKO7ICy12Ng=="; /** * 通过字符串生成私钥 */ public static PrivateKey getPrivateKey(String privateKeyData) { PrivateKey privateKey = null; try { byte[] decodeKey = Base64Decoder.decodeToBytes(privateKeyData); PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(decodeKey);//创建x509证书封装类 KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定RSA privateKey = keyFactory.generatePrivate(x509);//生成私钥 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return privateKey; } /** * 通过字符串生成公钥 */ public static PublicKey getPublicKey(String publicKeyData) { PublicKey publicKey = null; try { byte[] decodeKey = Base64Decoder.decodeToBytes(publicKeyData); X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); publicKey = keyFactory.generatePublic(x509); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return publicKey; } public static void main(String[] args) throws Exception { String jsonData = "abcdefghijklmnopqrstuvwxyz"; // KeyPair keyPair = RSAUtils.generateRSAKeyPair(RSAUtils.DEFAULT_KEY_SIZE); // RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 修改于 2017年5月2日14:35:18 #回复1楼评论 补上getPublicKey的实现 忘记贴了。 RSAPublicKey publicKey = (RSAPublicKey) getPublicKey(PUBLIC_KEY); System.out.println("RSAUtils publicKey ---->" + Base64Encoder.encode(publicKey.getEncoded())); RSAPrivateKey privateKey = (RSAPrivateKey) getPrivateKey(PRIVATE_KEY); System.out.println("RSAUtils privateKey ---->" + Base64Encoder.encode(privateKey.getEncoded())); //公钥加密 long start = System.currentTimeMillis(); byte[] encryptBytes = RSAUtils.encryptByPublicKeyForSpilt(jsonData.getBytes(), publicKey.getEncoded()); long end = System.currentTimeMillis(); System.out.println("RSAUtils public encrypt cost time---->" + (end - start)); String encryStr = Base64Encoder.encode(encryptBytes); System.out.println("RSAUtils jsonData(encrypted public) ---->" + encryStr); System.out.println("RSAUtils jsonData(encrypted public) length>" + encryStr.length()); //私钥解密 start = System.currentTimeMillis(); byte[] decryptBytes = RSAUtils.decryptByPrivateKeyForSpilt(Base64Decoder.decodeToBytes(encryStr), privateKey.getEncoded()); String decryStr = new String(decryptBytes); end = System.currentTimeMillis(); System.out.println("RSAUtils private decrypt cost time---->" + (end - start)); System.out.println("RSAUtils jsonData(decrypted private) ---->" + decryStr); //私钥加密 start = System.currentTimeMillis(); encryptBytes = RSAUtils.encryptByPrivateKeyForSpilt(jsonData.getBytes(), privateKey.getEncoded()); end = System.currentTimeMillis(); System.out.println("RSAUtils private encrypt cost time---->" + (end - start)); encryStr = Base64Encoder.encode(encryptBytes); System.out.println("RSAUtils jsonData(encrypted private) ---->" + encryStr); System.out.println("RSAUtils jsonData(encrypted private) length ---->" + encryStr.length()); //公钥解密 start = System.currentTimeMillis(); decryptBytes = RSAUtils.decryptByPublicKeyForSpilt(Base64Decoder.decodeToBytes(encryStr), publicKey.getEncoded()); decryStr = new String(decryptBytes); end = System.currentTimeMillis(); System.out.println("RSAUtils public decrypt cost time---->" + (end - start)); System.out.println("RSAUtils jsonData(decrypted public) ---->" + decryStr); }


运行结果

RSAUtils publicKey ---->MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj9O5dd2u4JWV6ca/Vn9Q7x4Y0nSqzOPq
tqYc3H3e2Ld7+1yInU4HsuYlg1uvgRr7msztyI0jRY9iZaIYhL3aPenbA9PnyxiAw1s7Pl8NwjFe
5fT2uLynu4wkrqA5sLMHVt/L2grAcp9C14Eo5CVuXtUk7JEqfVQoQ2SWj1N89Oe/Ubtgbv0j2Bdr
DwdW8+l+qIXA7AKRBh+HcdpHxnkVZDKfzBMNea7KjfFrqUvC6Q4GjbXG65sQ4rI/gX0iOD0BGlsF
0MKBLkbCmAW4DP6QaMsqbgsO3aMCvVHcn6MQvmPbfFA5uH1uMRhydr+m2XvggUS6YHm1tfCoYvby
BTcMMwIDAQAB
RSAUtils privateKey ---->MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCP07l13a7glZXpxr9Wf1DvHhjS
dKrM4+q2phzcfd7Yt3v7XIidTgey5iWDW6+BGvuazO3IjSNFj2JlohiEvdo96dsD0+fLGIDDWzs+
Xw3CMV7l9Pa4vKe7jCSuoDmwswdW38vaCsByn0LXgSjkJW5e1STskSp9VChDZJaPU3z0579Ru2Bu
/SPYF2sPB1bz6X6ohcDsApEGH4dx2kfGeRVkMp/MEw15rsqN8WupS8LpDgaNtcbrmxDisj+BfSI4
PQEaWwXQwoEuRsKYBbgM/pBoyypuCw7dowK9UdyfoxC+Y9t8UDm4fW4xGHJ2v6bZe+CBRLpgebW1
8Khi9vIFNwwzAgMBAAECggEARRF3zpJWmKM9CrbWy8L4KtxZLze3jg0lefDrizcm/QugDmWxdVkz
eUXsXdh5v5YlnYEr71NXzN++cPAWtig11eWnt37boTxzGV2GZb1f7hGncObiVHTEV9xFAVcQXTqc
G6v9SQhAwsqYXsU3zdfr2L6irLhJn0X6z+JOKyX8q96h1eZJVvGm0bQQTtIDAVHi0YpHt2rw/XBK
u4hYaLl8mxUU1e9g/HX6wz7GfzJSgIhMt0xbpJ19os0FT9Zh0OKgcUsN54D2Bf/ZGg/G2+QHRZX6
EE6bM7taThYtYi6wEAHaG0SsuUEfDtFLlGv5U5Xer1YvDoyRS9SRQJbtNDArAQKBgQDu3njuXprb
O16A8A1msuF+ncHBFBsdfxR/EUue+K25zyAwFMHS0GglfDX1nib09G47TbWbCflb35WSstHIfh09
anhneBk09NpMqZAaNaEtujBYV62VloD5EzWW8ZyEzghCUs9//76tyyl3BD0c2eblpeFqSsK3PE68
mNtOe4RkyQKBgQCaJFL7AGqhmxJwijLtn70huO0uSs17ye2u3qUkkL1je/CZRg4ESx9pYv8wTQ6J
FZgB6kozjVobkOLS1f4cXlWBJlskP0qzX+ZJNdaRpITLX14LbmeIGHyi5sFWAqdCrS+oBbjiWDF5
VpLA1Z7t9IalLXirijt8Qmb87U+3OtmTGwKBgEcxnZ+GKOeAqWkKoyPh2t2PDWmLoY1IDAbXU8+c
1MKVnkVWWnKH1RKfE8ISEhBeLeCVB7Se42hjmkPv8iCsnfBpJFvKatDizZGd1CpLo69qV/BsqXr1
MZmLBSTo/DqE4edKoTfINL+91qz3YXOQ6oW1zBqPD7vnSJxjfrHElLApAoGAUx+vmChbWJcV1JbS
bA6uodbmIQa51T3J7XmnuRZM669UynNa77nLULvQPi3v3sFEXhQIu9BIfYEesPAxvv6oQaN7lwqC
sETRHT3pXlVIP5xITQXW0y/RVs/2BvobVPusLYIYeAdzdqnXLiKFOHGbgswIvQkolxQAEfmv+XHF
D20CgYAcKij5wyvIAdCR7uDagIRYL4NFkuOFUPRrdh7mz+pw/aDhPGWbGTAl7VPPk1ixJA5vweuf
awOyoe4gZKGXVx8wqJhvUeL8ExgE45IX8xIjmBXBZEgGY4xlqBM5qFgP0jqKi4zPPNP9I0ga1sCQ
dj2rH2JUe8VW5tnfKO7ICy12Ng==
RSAUtils public encrypt cost time---->726
RSAUtils jsonData(encrypted public) ---->amicP8WaCWY/Xm4hZy1ehTca2Tst+bNmM+tUakJVMkLklfsLQqxaZ9dBBZJP429zKj7ywGz8pjoh
a3umErQR1FDvtON4qJnzDY/PEXCod0OsCqCdRrD4fIhT8MgNWz+u5oKBMv48/wpzAPUXCdpeeRw4
HOyRJf6yM8E6SvalMPVRWVo3bFPy72OLAG3Gxys/seJLwbPsdX0q6FdEDleczDcZu63hv6fD0wBF
jN4BdK60Op7i+0bk7O6sVb5MqpzM2jUNCnW115SP67Fccwdm2alJ0BeR+ZfAa/SeeXkGP+r+nGlW
qmDRNz7t0MgseisC3ik+Rs8JBj3qyp252v+RCQ==
RSAUtils jsonData(encrypted public) length>348
RSAUtils private decrypt cost time---->0
RSAUtils jsonData(decrypted private) ---->abcdefghijklmnopqrstuvwxyz
RSAUtils private encrypt cost time---->16
RSAUtils jsonData(encrypted private) ---->WHDpMf3jkjnwFcaOSseMvJOejn8torogdK6lhr6yfkmBRlarbKk5te3pNchxxzJme5a/Xm21wKHl
ro3uxisROOzjUBGq+YtSHIq76jJ/nxNCXm7elQTzLacifsV0GZx2MBw/AnsfMEuSshhVKD4Zx5H4
/plsQzgHrbV9jxI+wi1hwbc3xTADvdRV4aqFJ6Wuz58PCpFFEgWpnZQ7OtlWrW4dwN2ESpgXGqqc
7zFTDYm8t8e9wOSYAot0bTzRoVsdn/2szTQhb7/m1H25DO4xddrwWvxNjANfTEnflXLuUj2GAAIg
ZirfLMOLa4RaN9DMI9e5qjVMveWAryPPLre2yw==
RSAUtils jsonData(encrypted private) length ---->348
RSAUtils public decrypt cost time---->0
RSAUtils jsonData(decrypted public) ---->abcdefghijklmnopqrstuvwxyz



文章知识主要参考

http://www.cnblogs.com/AloneSword/p/3326750.html

http://www.cnblogs.com/whoislcj/p/5473030.html

简单整理出完整可运行的Demo内容。以便日后复制。。。

你可能感兴趣的:(Android)