RSA加密解密

来源:互联网 发布:加工中心proe软件 编辑:程序博客网 时间:2024/06/05 11:35

参考了网上的一些资料:

http://blog.sina.com.cn/s/blog_76550fd7010147tp.html 

http://blog.csdn.net/centralperk/article/details/8538697

http://dustin.iteye.com/blog/763931

RSA算法密钥长度的选择是安全性和程序性能平衡的结果,密钥长度越长,安全性越好,加密解密所需时间越长。

1. 非对称加密算法中1024 bit密钥的强度相当于对称加密算法80bit密钥的强度。有资料上说以当前的软硬件水平,破解1024bit的RSA加密密文,需要一套10亿美金的系统使用若干十年的时间,所以2015年前,1024bit的还无需太担心暴力破解的危险。

2. 密钥长度增长一倍,公钥操作所需时间增加约4倍,私钥操作所需时间增加约8倍,公私钥生成时间约增长16倍。

3. 一次能加密的密文长度与密钥长度成正比, len_in_byte(raw_data) = len_in_bit(key)/8 -11,如1024bit的密钥,一次能加密的内容长度为 1024/8 -11 = 117 byte。所以非对称加密一般都用于加密对称加密算法的密钥,而不是直接加密内容。

4. 加密后密文的长度为密钥的长度,如密钥长度为1024b(128Byte),最后生成的密文固定为 1024b(128Byte)

现整理如下:

import java.io.*;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;public class RSAUtil{    private  static final String KEY_ALGORITHM = "RSA";//签名算法     /**     * RSA解密要求密文最大长度为128字节,加密明文最大长度117字节       * 如果加密数据过大需要在加密和解密的过程中需要分块进行     * 块数=(明文长度(bytes)/(密钥长度(需要将bit转换为bytes)-11))向上取整,就是不满一片的按一片算     * 所以密文的长度设置直接影响块数的大小,可以根据项目需要灵活分配分块的个数     * RSA最大密文长度 单位:byte     */    private  static final int DECRYPT_LENGTH = 128;    /**     * RSA最大明文长度 单位:byte     */    private  static final int ENCRYPT_LENGTH = DECRYPT_LENGTH - 11;    /** *密钥长度 单位:bit  1byte=8bit  *加密n byte的明文,需要至少(n+11)bytes的密钥 *因为该单位是bit 所以换算成bit就要乘以8 */    private  static final int ENCRYTLENGTH = (ENCRYPT_LENGTH + 11) * 8;    /**     * 注意下面两个路径必须存在,否则在初始化过程中会发生异常     */    private  static final String PUBLICKEYPATH = "/home/key/public.key";    private  static final String PRIVATEKEYPATH = "/home/key/private.key";    private  static RSAPublicKey publicKey;    private  static RSAPrivateKey privateKey;    public enum KeyType{ PUBLIC,PRIVATE; }    static{        try {            initKey(true);        } catch (Exception e) {        e.printStackTrace();            throw new RuntimeException("初始化key异常!!");        }    }        public static void main(String[] args) throws Exception {        String data = "hello world";        File publickeyFile = new File(PUBLICKEYPATH);        File privatekeyFile = new File(PRIVATEKEYPATH);        byte[] encryptData,decryptData;        if(publickeyFile.exists() && privatekeyFile.exists()){        Key publickey = getKey(publickeyFile, KeyType.PUBLIC);        Key privatekey = getKey(privatekeyFile, KeyType.PRIVATE);        encryptData = encrypt(data.getBytes(), publickey);        decryptData = decrypt(encryptData, privatekey);        System.out.println("用文件路径方式的key进行加密!!!");        }else{        encryptData = encrypt(data.getBytes());        decryptData = decrypt(encryptData);        System.out.println("用系统初始化的key进行加密!!!");        }        System.out.println("加密后:" + new String(encryptData, "UTF-8"));    System.out.println(new String(decryptData));            }    /**     * @param isSaveKey //初始化是否将key保存为文件 true是 false不是     * @throws Exception     */    private static void initKey(boolean isSaveKey) throws Exception {        KeyPairGenerator kg = KeyPairGenerator.getInstance(KEY_ALGORITHM);        kg.initialize(ENCRYTLENGTH);        KeyPair keypair = kg.generateKeyPair();        //得到公钥和私钥        publicKey = (RSAPublicKey) keypair.getPublic();        privateKey = (RSAPrivateKey) keypair.getPrivate();        if(isSaveKey){        File publicKeyFile = new File(PUBLICKEYPATH);        File privateKeyFile = new File(PRIVATEKEYPATH);        if(publicKeyFile.exists() && privateKeyFile.exists()){        generateKeyToFile(publicKey,  publicKeyFile);        generateKeyToFile(privateKey, privateKeyFile);        }else{        throw new RuntimeException("生成key文件的路径错误!!!");        }        }    }    /**     * 将key生成到文件     * @param key     * @param file     * @return     * @throws IOException     */    private static boolean generateKeyToFile(Key key,File file) throws IOException {        boolean flag = false;        FileOutputStream fos = null;        ObjectOutputStream oos = null;        try {            fos = new FileOutputStream(file);            oos = new ObjectOutputStream(fos);            //公钥默认使用的是X.509编码,私钥默认采用的是PKCS8编码            byte [] encode = key.getEncoded();            //注意,此处采用writeObject方法,读取时也要采用readObject方法            oos.writeObject(encode);            flag = true;        } catch (IOException e) {            throw e;        } finally {            if(fos != null) fos.close();            if(oos != null) oos.close();        }        return flag;    }    /**     * @param keybyte     * @param type     * @return     * @throws Exception     */    private static Key getKey( byte[] keybyte, KeyType type) throws Exception {    KeyFactory keyfactory = KeyFactory.getInstance(KEY_ALGORITHM);        if (type == KeyType.PUBLIC) {            X509EncodedKeySpec x509eks = new X509EncodedKeySpec(keybyte);            RSAPublicKey publicKey = (RSAPublicKey) keyfactory.generatePublic(x509eks);            return publicKey;        } else if (type == KeyType.PRIVATE) {            PKCS8EncodedKeySpec pkcs8eks = new PKCS8EncodedKeySpec(keybyte);            RSAPrivateKey privateKey = (RSAPrivateKey) keyfactory.generatePrivate(pkcs8eks);            return privateKey;        }        return null;    }    /**     * @param keyFile     * @param type     * @return     * @throws Exception     */    private static Key getKey(File keyFile, KeyType type) throws Exception {        FileInputStream fis = new FileInputStream(keyFile);        ObjectInputStream ois = new ObjectInputStream(fis);        byte[] keybyte = (byte[]) ois.readObject();        ois.close();        return getKey(keybyte,type);    }    /**     * @param type     * @return     * @throws Exception     */    private static Key getKey(KeyType type) throws Exception {        if (type == KeyType.PUBLIC) {           return publicKey;        } else if (type == KeyType.PRIVATE) {            return privateKey;        }        return null;    }    /**     * @param data     * @param publicKey     * @return     * @throws Exception     */    private static byte[] encrypt(byte[] data, Key publicKey) throws Exception {        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);        cipher.init(Cipher.ENCRYPT_MODE, publicKey);        int inputLen = data.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;        // 对数据分段加密        while (inputLen - offSet > 0) {            if (inputLen - offSet > ENCRYPT_LENGTH) {                cache = cipher.doFinal(data, offSet, ENCRYPT_LENGTH);            } else {                cache = cipher.doFinal(data, offSet, inputLen - offSet);            }            out.write(cache, 0, cache.length);            i++;            offSet = i * ENCRYPT_LENGTH;        }        byte[] encryptedData = out.toByteArray();        out.close();        return encryptedData;    }        /**     * @param data     * @param keyFile     * @return     * @throws Exception     */    public static byte[] encrypt(byte[] data,File keyFile) throws Exception {     Key publicKey = getKey(keyFile, KeyType.PUBLIC);     return encrypt(data,publicKey);    }    /**     * @param data     * @param keyByte     * @return     * @throws Exception     */    public static byte[] encrypt(byte[] data,byte[] keyByte) throws Exception {    Key publicKey = getKey(keyByte,KeyType.PUBLIC);        return encrypt(data,publicKey);    }    /**     * @param data     * @return     * @throws Exception     */    public static byte[] encrypt(byte[] data) throws Exception {    return encrypt(data,publicKey);    }    /**     *     * @param data     * @param privateKey     * @return     * @throws Exception     */    private static byte[] decrypt(byte[] data, Key privateKey) throws Exception {        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);        cipher.init(Cipher.DECRYPT_MODE, privateKey);        int inputLen = data.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;       // 对数据分段解密        while (inputLen - offSet > 0) {            if (inputLen - offSet > DECRYPT_LENGTH) {                cache = cipher.doFinal(data, offSet, DECRYPT_LENGTH);            } else {                cache = cipher.doFinal(data, offSet, inputLen - offSet);            }            out.write(cache, 0, cache.length);            i++;            offSet = i * DECRYPT_LENGTH;        }        byte[] decryptedData = out.toByteArray();        out.close();        return decryptedData;    }    /**     * @param data     * @param privateKeyBytes     * @return     * @throws Exception     */    public static byte[] decrypt(byte[] data, byte[] privateKeyBytes) throws Exception {        Key privateKey = getKey(privateKeyBytes,KeyType.PRIVATE);        return decrypt(data,privateKey);    }    /**     * @param data     * @param keyFile     * @return     * @throws Exception     */    public static byte[] decrypt(byte[] data,File keyFile) throws Exception {    Key privateKey = getKey(keyFile, KeyType.PRIVATE);    return decrypt(data,privateKey);   }    /**     * @param data     * @return     * @throws Exception     */    public static byte[] decrypt(byte[] data) throws Exception {        return decrypt(data,privateKey);    }}


0 0
原创粉丝点击