鉴于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
闽公网安备 35060202000074号