安卓RSA加密解密

来源:互联网 发布:千驮谷日本语学校 知乎 编辑:程序博客网 时间:2024/05/21 18:34
package com.animee.day20.utils;import java.io.ByteArrayOutputStream;import java.security.Key;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;/** * Created by Administrator on 2017/11/21. */public class RSAUtils {    public static  final String PUBLIC_KEY="publickey";    public static  final String PRIVATE_KEY="privatekey";    /**     * 计算出公钥私钥用map存储     * @return     * @throws Exception     */    public static Map<String, Object> genKeyPair() throws Exception {        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");        //这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低        keyPairGen.initialize(1024);        KeyPair keyPair = keyPairGen.generateKeyPair();        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();        Map<String, Object> keyMap = new HashMap<String, Object>(2);        keyMap.put(PUBLIC_KEY, publicKey);        keyMap.put(PRIVATE_KEY, privateKey);        return keyMap;    }    /**     * <p>     * 获取私钥     * </p>     *     * @param keyMap 密钥对     * @return     * @throws Exception     */    public static Key getPrivateKey(Map<String, Object> keyMap)            throws Exception {        Key key = (Key) keyMap.get(PRIVATE_KEY);        return key;    }    /**     * 获取公钥     * @param keyMap 密钥对     * @return     * @throws Exception     */    public static Key getPublicKey(Map<String, Object> keyMap)            throws Exception {        Key key = (Key) keyMap.get(PUBLIC_KEY);        return key;    }    /**     * 加密     * @param key  加密的密钥     * @param data 待加密的明文数据     * @return 加密后的数据     * @throws Exception     */    public static byte[] encrypt(Key key, byte[] data) throws Exception {        try {            Cipher cipher = Cipher.getInstance("RSA");            cipher.init(Cipher.ENCRYPT_MODE, key);            //获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;            //因此共有2个加密块,第一个127 byte第二个为1个byte            int blockSize = cipher.getBlockSize();            int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小            int leavedSize = data.length % blockSize;            int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;            byte[] raw = new byte[outputSize * blocksSize];            int i = 0;            while (data.length - i * blockSize > 0) {                if (data.length - i * blockSize > blockSize)                    cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);                else                    cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);                //这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中                //,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。                i++;            }            return raw;        } catch (Exception e) {            throw new Exception(e.getMessage());        }    }    /**     * 解密     * @param key 解密的密钥     * @param raw 已经加密的数据     * @return 解密后的明文     * @throws Exception     */    public static byte[] decrypt(Key key, byte[] raw) throws Exception {        try {            Cipher cipher = Cipher.getInstance("RSA");            cipher.init(cipher.DECRYPT_MODE, key);            int blockSize = cipher.getBlockSize();            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);            int j = 0;            while (raw.length - j * blockSize > 0) {                bout.write(cipher.doFinal(raw, j * blockSize, blockSize));                j++;            }            return bout.toByteArray();        } catch (Exception e) {            throw new Exception(e.getMessage());        }    }}
原创粉丝点击