服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

java安全:java非对称加密源代码(rsa)

鉴于rsa加密的重要性和相关源代码的匮乏,经过整理特此贴出。需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。 

import javax.crypto.cipher;
import java.security.*;
import java.security.spec.rsapublickeyspec;
import java.security.spec.rsaprivatekeyspec;
import java.security.spec.invalidkeyspecexception;
import java.security.interfaces.rsaprivatekey;
import java.security.interfaces.rsapublickey;
import java.io.*;
import java.math.biginteger;

/**
 * rsa 工具类。提供加密,解密,生成密钥对等方法。
 * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。 
 * @author xiaoyusong 
 *          mail: xiaoyusong@etang.com 
 *          msn:xiao_yu_song@hotmail.com 
 * @since 2004-5-20
 * 
 */ 
public class rsautil {

    /**
     * 生成密钥对
     * @return keypair
     * @throws encryptexception
     */
    public static keypair generatekeypair() throws encryptexception {
        try {
            keypairgenerator keypairgen = keypairgenerator.getinstance("rsa",
                    new org.bouncycastle.jce.provider.bouncycastleprovider());
            final int key_size = 1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
            keypairgen.initialize(key_size, new securerandom());
            keypair keypair = keypairgen.genkeypair();
            return keypair;
        } catch (exception e) {
            throw new encryptexception(e.getmessage());
        }
    }
    /**
     * 生成公钥
     * @param modulus
     * @param publicexponent
     * @return rsapublickey
     * @throws encryptexception
     */
    public static rsapublickey generatersapublickey(byte[] modulus, byte[] publicexponent) throws encryptexception {
        keyfactory keyfac = null;
        try {
            keyfac = keyfactory.getinstance("rsa", new org.bouncycastle.jce.provider.bouncycastleprovider());
        } catch (nosuchalgorithmexception ex) {
            throw new encryptexception(ex.getmessage());
        }

        rsapublickeyspec pubkeyspec = new rsapublickeyspec(new biginteger(modulus), new biginteger(publicexponent));
        try {
            return (rsapublickey) keyfac.generatepublic(pubkeyspec);
        } catch (invalidkeyspecexception ex) {
            throw new encryptexception(ex.getmessage());
        }
    }
    /**
     * 生成私钥
     * @param modulus
     * @param privateexponent
     * @return rsaprivatekey
     * @throws encryptexception
     */
    public static rsaprivatekey generatersaprivatekey(byte[] modulus, byte[] privateexponent) throws encryptexception {
        keyfactory keyfac = null;
        try {
            keyfac = keyfactory.getinstance("rsa", new org.bouncycastle.jce.provider.bouncycastleprovider());
        } catch (nosuchalgorithmexception ex) {
            throw new encryptexception(ex.getmessage());
        }

        rsaprivatekeyspec prikeyspec = new rsaprivatekeyspec(new biginteger(modulus), new biginteger(privateexponent));
        try {
            return (rsaprivatekey) keyfac.generateprivate(prikeyspec);
        } catch (invalidkeyspecexception ex) {
            throw new encryptexception(ex.getmessage());
        }
    }
    /**
     * 加密
     * @param key 加密的密钥
     * @param data 待加密的明文数据
     * @return 加密后的数据
     * @throws encryptexception
     */
    public static byte[] encrypt(key key, byte[] data) throws encryptexception {
        try {
            cipher cipher = cipher.getinstance("rsa", new org.bouncycastle.jce.provider.bouncycastleprovider());
            cipher.init(cipher.encrypt_mode, key);
            int blocksize = cipher.getblocksize();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;因此共有2个加密块,第一个127 byte第二个为1个byte
            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 encryptexception(e.getmessage());
        }
    }
    /**
     * 解密
     * @param key 解密的密钥
     * @param raw 已经加密的数据
     * @return 解密后的明文
     * @throws encryptexception
     */
    public static byte[] decrypt(key key, byte[] raw) throws encryptexception {
        try {
            cipher cipher = cipher.getinstance("rsa", new org.bouncycastle.jce.provider.bouncycastleprovider());
            cipher.init(cipher.decrypt_mode, key);
            int blocksize = cipher.getblocksize();
            bytearrayoutputstream bout = new bytearrayoutputstrea

扫描关注微信公众号