當前位置:ag真人国际官网-ag旗舰厅官方网站 » 操作系統 » rsa演算法的java實現

rsa演算法的java實現-ag真人国际官网

發布時間: 2024-07-13 14:52:57

㈠ 非對稱加密解密rsa的實現例子

最近有接觸到加密相關的內容,本期以非對稱加密為例子,做個簡單的總結和記錄。首先了解下非對稱加密,簡單來說非對稱指的是加密和解密用不同的秘鑰,典型的rsa,這個演算法名稱是基於三個發明人的名字首字母取的;辯含碧而對稱加密必須要在加解密使用相同的秘鑰攜舉,典型的aes。這里細節不多展開闡述,涉及到很多數學原理,如大數的質因數分解等,感興趣的可以找找李永樂等網上比較優秀的科普。這篇文章只是java原生實現的加解密例子。至於其他的如md5,hash等,如果從主觀可讀的角度來說,也可以稱為加密。

如下的示例是使用java原生實現rsa的加密解密,包括用公鑰加密,然後私鑰解密;或者使用私鑰加密,然後公鑰解密。注意不同key大小,限制的解密內容大小也不一樣,感老備興趣的同學可以試試修改key大小和加密內容長度來試試。還有要注意的是rsa加密有一定的性能損耗。

想了解原理相關的內容可以看如下的參考內容。
[1]. rsa原理

㈡ 求java編寫的rsa加密演算法

代碼如下:main方法用於測試的,不是演算法本身。

import java.security.keypair;
import java.security.keypairgenerator;
import java.security.privatekey;
import java.security.publickey;
import java.security.securerandom;

import javax.crypto.cipher;

public class rsacrypto
{
private final static string rsa = "rsa";
public static publickey uk;
public static privatekey rk;

public static void generatekey() throws exception
{
keypairgenerator gen = keypairgenerator.getinstance(rsa);
gen.initialize(512, new securerandom());
keypair keypair = gen.generatekeypair();
uk = keypair.getpublic();
rk = keypair.getprivate();
}

private static byte[] encrypt(string text, publickey pubrsa) throws exception
{
cipher cipher = cipher.getinstance(rsa);
cipher.init(cipher.encrypt_mode, pubrsa);
return cipher.dofinal(text.getbytes());
}

public final static string encrypt(string text)
{
try {
return byte2hex(encrypt(text, uk));
}
catch(exception e)
{
e.printstacktrace();
}
return null;
}

public final static string decrypt(string data)
{
try{
return new string(decrypt(hex2byte(data.getbytes())));
}
catch (exception e)
{
e.printstacktrace();
}
return null;
}

private static byte[] decrypt(byte[] src) throws exception
{
cipher cipher = cipher.getinstance(rsa);
cipher.init(cipher.decrypt_mode, rk);
return cipher.dofinal(src);
}

public static string byte2hex(byte[] b)
{
string hs = "";
string stmp = "";
for (int n = 0; n < b.length; n )
{
stmp = integer.tohexstring(b[n] & 0xff);
if (stmp.length() == 1)
hs = ("0" stmp);
else
hs = stmp;
}
return hs.touppercase();
}

public static byte[] hex2byte(byte[] b)
{
if ((b.length % 2) != 0)
throw new illegalargumentexception("長度不是偶數");

byte[] b2 = new byte[b.length / 2];

for (int n = 0; n < b.length; n = 2)
{
string item = new string(b, n, 2);
b2[n/2] = (byte)integer.parseint(item, 16);
}
return b2;
}

//just for test
public static void main(string args[])
{
try
{
rsacrypto.generatekey();
string ciphertext = rsacrypto.encrypt("asdfghjh");
system.out.println(ciphertext);
string plaintext = rsacrypto.decrypt(ciphertext);
system.out.println(plaintext);
}
catch(exception e)
{
e.printstacktrace();
}
}

}

㈢ 我想把java文件先加密然後打包,請高手指教怎麼加密,有那種好的加密演算法嗎

rsa演算法非常簡單,概述如下:
找兩素數p和q
取n=p*q
取t=(p-1)*(q-1)
取任何一個數e,要求滿足e取d*e%t==1

這樣最終得到三個數: n d e

設消息為數m (m 設c=(m**d)%n就得到了加密後的消息c
設m=(c**e)%n則 m == m,從而完成對c的解密。
註:**表示次方,上面兩式中的d和e可以互換。

在對稱加密中:
n d兩個數構成公鑰,可以告訴別人;
n e兩個數構成私鑰,e自己保留,不讓任何人知道。
給別人發送的信息使用e加密,只要別人能用d解開就證明信息是由你發送的,構成了簽名機制。
別人給你發送信息時使用d加密,這樣只有擁有e的你能夠對其解密。

rsa的安全性在於對於一個大數n,沒有有效的方法能夠將其分解
從而在已知n d的情況下無法獲得e;同樣在已知n e的情況下無法
求得d。

<二>實踐

接下來我們來一個實踐,看看實際的操作:
找兩個素數:
p=47
q=59
這樣
n=p*q=2773
t=(p-1)*(q-1)=2668
取e=63,滿足e用perl簡單窮舉可以獲得滿主 e*d%t ==1的數d:
c:\temp>perl -e "foreach $i (1..9999){ print($i),last if $i*63&68==1 }"
847
即d=847

最終我們獲得關鍵的
n=2773
d=847
e=63

取消息m=244我們看看

加密:

c=m**d%n = 244**847'73
用perl的大數計算來算一下:
c:\temp>perl -mbigint -e "print 244**847'73"
465
即用d對m加密後獲得加密信息c=465

解密:

我們可以用e來對加密後的c進行解密,還原m:
m=c**e%n=465**63'73 :
c:\temp>perl -mbigint -e "print 465**63'73"
244
即用e對c解密後獲得m=244 , 該值和原始信息m相等。

<三>字元串加密

把上面的過程集成一下我們就能實現一個對字元串加密解密的示例了。
每次取字元串中的一個字元的ascii值作為m進行計算,其輸出為加密後16進制
的數的字元串形式,按3位元組表示,如01f

代碼如下:

#!/usr/bin/perl -w
#rsa 計算過程學習程序編寫的測試程序
#watercloud 2003-8-12
#
use strict;
use math::bigint;

my %rsa_core = (n=>2773,e=>63,d=>847); #p=47,q=59

my $n=new math::bigint($rsa_core{n});
my $e=new math::bigint($rsa_core{e});
my $d=new math::bigint($rsa_core{d});

print "n=$n d=$d e=$e\n";

sub rsa_encrypt
{
my $r_mess = shift @_;
my ($c,$i,$m,$c,$cmess);

for($i=0;$i < length($$r_mess);$i )
{
$c=ord(substr($$r_mess,$i,1));
$m=math::bigint->new($c);
$c=$m->(); $c->bmodpow($d,$n);
$c=sprintf "x",$c;
$cmess.=$c;
}
return \$cmess;
}

sub rsa_decrypt
{
my $r_mess = shift @_;
my ($c,$i,$m,$c,$dmess);

for($i=0;$i < length($$r_mess);$i =3)
{
$c=substr($$r_mess,$i,3);
$c=hex($c);
$m=math::bigint->new($c);
$c=$m->(); $c->bmodpow($e,$n);
$c=chr($c);
$dmess.=$c;
}
return \$dmess;
}

my $mess="rsa 娃哈哈哈~~~";
$mess=$argv[0] if @argv >= 1;
print "原始串:",$mess,"\n";

my $r_cmess = rsa_encrypt(\$mess);
print "加密串:",$$r_cmess,"\n";

my $r_dmess = rsa_decrypt($r_cmess);
print "解密串:",$$r_dmess,"\n";

#eof

測試一下:
c:\temp>perl rsa-test.pl
n=2773 d=847 e=63
原始串:rsa 娃哈哈哈~~~
加密串:
解密串:rsa 娃哈哈哈~~~

c:\temp>perl rsa-test.pl 安全焦點(xfocus)
n=2773 d=847 e=63
原始串:安全焦點(xfocus)
加密串:
解密串:安全焦點(xfocus)

<四>提高

前面已經提到,rsa的安全來源於n足夠大,我們測試中使用的n是非常小的,根本不能保障安全性,
我們可以通過rsakit、rsatool之類的工具獲得足夠大的n 及d e。
通過工具,我們獲得1024位的n及d e來測試一下:

n=ec3a85f5005d
4c2013433b383b
a50e114705d7e2
bc511951

d=0x10001

e=dd28c523c2995
47b77324e66aff2
789bd782a592d2b
1965

設原始信息
m=

完成這么大數字的計算依賴於大數運算庫,用perl來運算非常簡單:

a) 用d對m進行加密如下:
c=m**d%n :
c:\temp>perl -mbigint -e " $x=math::bigint->bmodpow(0x11111111111122222222222233
333333333, 0x10001,
d55edbc4f0
6e37108dd6
);print $x->as_hex"
b73d2576bd
47715caa6b
d59ea89b91
f1834580c3f6d90898

即用d對m加密後信息為:
c=b73d2576bd
47715caa6b
d59ea89b91
f1834580c3f6d90898

b) 用e對c進行解密如下:

m=c**e%n :
c:\temp>perl -mbigint -e " $x=math::bigint->bmodpow(0x17b287be418c69ecd7c39227ab
5aa1d99ef3
0cb4764414
, 0xe760a
3c29954c5d
7324e66aff
2789bd782a
592d2b1965, cd15f90
4f017f9ccf
dd60438941
);print $x->as_hex"

(我的p4 1.6g的機器上計算了約5秒鍾)

得到用e解密後的m= == m

c) rsa通常的實現
rsa簡潔幽雅,但計算速度比較慢,通常加密中並不是直接使用rsa 來對所有的信息進行加密,
最常見的情況是隨機產生一個對稱加密的密鑰,然後使用對稱加密演算法對信息加密,之後用
rsa對剛才的加密密鑰進行加密。

最後需要說明的是,當前小於1024位的n已經被證明是不安全的
自己使用中不要使用小於1024位的rsa,最好使用2048位的。

----------------------------------------------------------

一個簡單的rsa演算法實現java源代碼:

filename:rsa.java

/*
* created on mar 3, 2005
*
* todo to change the template for this generated file go to
* window - preferences - java - code style - code templates
*/

import java.math.biginteger;
import java.io.inputstream;
import java.io.outputstream;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.filenotfoundexception;
import java.io.ioexception;
import java.io.filewriter;
import java.io.filereader;
import java.io.bufferedreader;
import java.util.stringtokenizer;

/**
* @author steve
*
* todo to change the template for this generated type comment go to
* window - preferences - java - code style - code templates
*/
public class rsa {

/**
* biginteger.zero
*/
private static final biginteger zero = biginteger.zero;

/**
* biginteger.one
*/
private static final biginteger one = biginteger.one;

/**
* pseudo biginteger.two
*/
private static final biginteger two = new biginteger("2");

private biginteger mykey;

private biginteger mymod;

private int blocksize;

public rsa (biginteger key, biginteger n, int b) {
mykey = key;
mymod = n;
blocksize = b;
}

public void encodefile (string filename) {
byte[] bytes = new byte[blocksize / 8 1];
byte[] temp;
int templen;
inputstream is = null;
filewriter writer = null;
try {
is = new fileinputstream(filename);
writer = new filewriter(filename ".enc");
}
catch (filenotfoundexception e1){
system.out.println("file not found: " filename);
}
catch (ioexception e1){
system.out.println("file not found: " filename ".enc");
}

/**
* write encoded message to 'filename'.enc
*/
try {
while ((templen = is.read(bytes, 1, blocksize / 8)) > 0) {
for (int i = templen 1; i < bytes.length; i) {
bytes[i] = 0;
}
writer.write(encodedecode(new biginteger(bytes)) " ");
}
}
catch (ioexception e1) {
system.out.println("error writing to file");
}

/**
* close input stream and file writer
*/
try {
is.close();
writer.close();
}
catch (ioexception e1) {
system.out.println("error closing file.");
}
}

public void decodefile (string filename) {

filereader reader = null;
outputstream os = null;
try {
reader = new filereader(filename);
os = new fileoutputstream(filename.replaceall(".enc", ".dec"));
}
catch (filenotfoundexception e1) {
if (reader == null)
system.out.println("file not found: " filename);
else
system.out.println("file not found: " filename.replaceall(".enc", "dec"));
}

bufferedreader br = new bufferedreader(reader);
int offset;
byte[] temp, tofile;
stringtokenizer st = null;
try {
while (br.ready()) {
st = new stringtokenizer(br.readline());
while (st.hasmoretokens()){
tofile = encodedecode(new biginteger(st.nexttoken())).tobytearray();
system.out.println(tofile.length " x " (blocksize / 8));

if (tofile[0] == 0 && tofile.length != (blocksize / 8)) {
temp = new byte[blocksize / 8];
offset = temp.length - tofile.length;
for (int i = tofile.length - 1; (i <= 0) && ((i offset) <= 0); --i) {
temp[i offset] = tofile[i];
}
tofile = temp;
}

/*if (tofile.length != ((blocksize / 8) 1)){
temp = new byte[(blocksize / 8) 1];
system.out.println(tofile.length " x " temp.length);
for (int i = 1; i < temp.length; i ) {
temp[i] = tofile[i - 1];
}
tofile = temp;
}
else
system.out.println(tofile.length " " ((blocksize / 8) 1));*/
os.write(tofile);
}
}
}
catch (ioexception e1) {
system.out.println("something went wrong");
}

/**
* close data streams
*/
try {
os.close();
reader.close();
}
catch (ioexception e1) {
system.out.println("error closing file.");
}
}

/**
* performs base^pow within the molar
* domain of mod.
*
* @param base the base to be raised
* @param pow the power to which the base will be raisded
* @param mod the molar domain over which to perform this operation
* @return base^pow within the molar
* domain of mod.
*/
public biginteger encodedecode(biginteger base) {
biginteger a = one;
biginteger s = base;
biginteger n = mykey;

while (!n.equals(zero)) {
if(!n.mod(two).equals(zero))
a = a.multiply(s).mod(mymod);

s = s.pow(2).mod(mymod);
n = n.divide(two);
}

return a;
}

}

在這里提供兩個版本的rsa演算法java實現的代碼下載:

1. 來自於 http://www.javafr.com/code.aspx?id=27020 的rsa演算法實現源代碼包:
http://zeal.newmenbase.net/attachment/javafr_rsa_source.rar

2. 來自於 http://www.ferrara.linux.it/members/lucabariani/rsa/implementazionersa/ 的實現:
http://zeal.newmenbase.net/attachment/sorgentijava.tar.gz - 源代碼包
http://zeal.newmenbase.net/attachment/algoritmorsa.jar - 編譯好的jar包

另外關於rsa演算法的php實現請參見文章:
php下的rsa演算法實現

關於使用vb實現rsa演算法的源代碼下載(此程序採用了psc1演算法來實現快速的rsa加密):
http://zeal.newmenbase.net/attachment/vb_psc1_rsa.rar

rsa加密的javascript實現: http://www.ohdave.com/rsa/
參考資料:http://www.lenovonet.com/proct/showarticle.asp?id=118

㈣ java rsa演算法實現256位密鑰怎麼做

【下載實例】本文介紹rsa2加密與解密,rsa2是rsa的加強版本,在密鑰長度上採用2048, rsa2比rsa更安全,更可靠, 本人的另一篇文章rsa已經發表,有想了解的可以點開下面的rsa文章

㈤ java中rsa的方式如何實現非對稱加密的示例

代碼如下,需要依賴一個jar包commons-codec-1.9.jar,用於base64轉換,請自行下載。

importorg.apache.commons.codec.binary.base64;

importjavax.crypto.badpaddingexception;
importjavax.crypto.cipher;
importjavax.crypto.illegalblocksizeexception;
importjava.io.bytearrayoutputstream;
importjava.io.unsupportedencodingexception;
importjava.security.*;
importjava.security.interfaces.rsaprivatekey;
importjava.security.interfaces.rsapublickey;
importjava.security.spec.pkcs8encodedkeyspec;
importjava.security.spec.x509encodedkeyspec;

publicclassrsautils{

//加密方式
="rsa";
//簽名演算法
_algorithm="sha1withrsa";
//創建密鑰對初始長度
privatestaticfinalintkey_size=512;
//字元編碼格式
="utf-8";
//rsa最大加密明文大小
privatestaticfinalintmax_encrypt_block=117;
//rsa最大解密密文大小
privatestaticfinalintmax_decrypt_block=128;

privatekeyfactorykeyfactory;

publicrsautils(){
keyfactory=keyfactory.getinstance(algorithm);
}

/**
*私鑰加密
*
*@paramcontent待加密字元串
*@paramprivatekey私鑰
*@return加密後字元串(base64編碼)
*/
(stringcontent,stringprivatekey)throwsexception{
stringresult;

try(bytearrayoutputstreamout=newbytearrayoutputstream()){
byte[]keybytes=newbase64().decode(privatekey);
=newpkcs8encodedkeyspec(keybytes);
privatekeypkey=keyfactory.generateprivate(pkcs8keyspec);
ciphercipher=cipher.getinstance(algorithm);
cipher.init(cipher.encrypt_mode,pkey);

byte[]data=content.getbytes(charset);
write2stream(cipher,data,out);
byte[]resultbytes=out.tobytearray();

result=base64.encodebase64string(resultbytes);
}catch(exceptione){
thrownewexception(e);
}

returnresult;
}

/**
*公鑰解密
*
*@paramcontent已加密字元串(base64加密)
*@parampublickey公鑰
*@return
*/
(stringcontent,stringpublickey)throwsexception{
stringresult="";

try(bytearrayoutputstreamout=newbytearrayoutputstream()){
byte[]keybytes=newbase64().decode(publickey);
x509encodedkeyspecx509keyspec=newx509encodedkeyspec(keybytes);
publickeypkey=keyfactory.generatepublic(x509keyspec);
ciphercipher=cipher.getinstance(algorithm);
cipher.init(cipher.decrypt_mode,pkey);

byte[]data=base64.decodebase64(content);
write2stream(cipher,data,out);
byte[]resultbytes=out.tobytearray();

result=newstring(resultbytes);
}catch(exceptione){
thrownewexception(e);
}

returnresult;
}

/**
*公鑰加密
*
*@paramcontent待加密字元串
*@parampublickey公鑰
*@return加密後字元串(base64編碼)
*/
(stringcontent,stringpublickey)throwsexception{
stringresult="";

try(bytearrayoutputstreamout=newbytearrayoutputstream()){
byte[]keybytes=newbase64().decode(publickey);
x509encodedkeyspecx509keyspec=newx509encodedkeyspec(keybytes);
publickeypkey=keyfactory.generatepublic(x509keyspec);
ciphercipher=cipher.getinstance(algorithm);
cipher.init(cipher.encrypt_mode,pkey);

byte[]data=content.getbytes(charset);
write2stream(cipher,
data,out);
byte[]resultbytes=out.tobytearray();
result=base64.encodebase64string(resultbytes);
}catch(exceptione){
thrownewexception(e);
}

returnresult;
}

/**
*私鑰解密
*
*@paramcontent已加密字元串
*@paramprivatekey私鑰
*@return解密後字元串
*/
(stringcontent,stringprivatekey)throwsexception{
stringresult="";

try(bytearrayoutputstreamout=newbytearrayoutputstream()){
byte[]keybytes=newbase64().decode(privatekey);
=newpkcs8encodedkeyspec(keybytes);
privatekeypkey=keyfactory.generateprivate(pkcs8keyspec);
ciphercipher=cipher.getinstance(algorithm);
cipher.init(cipher.decrypt_mode,pkey);

byte[]data=base64.decodebase64(content);
write2stream(cipher,data,out);
byte[]resultbytes=out.tobytearray();
result=newstring(resultbytes);
}catch(exceptione){
thrownewexception(e);
}

returnresult;
}

privatestaticvoidwrite2stream(ciphercipher,byte[]data,bytearrayoutputstreamout)throws
badpaddingexception,illegalblocksizeexception{
intdatalen=data.length;
intoffset=0;
byte[]cache;
inti=0;
//對數據分段解密
while(datalen-offset>0){
if(datalen-offset>max_decrypt_block){
cache=cipher.dofinal(data,offset,max_decrypt_block);
}else{
cache=cipher.dofinal(data,offset,datalen-offset);
}
out.write(cache,0,cache.length);
i ;
offset=i*max_decrypt_block;
}
}

/**
*用私鑰對信息生成數字簽名
*
*@paramdata已加密數據
*@paramprivatekey私鑰(base64編碼)
*@returnsign
*/
publicstringsign(stringdata,stringprivatekey)throwsexception{
stringresult="";
try{
byte[]keybytes=newbase64().decode(privatekey);
=newpkcs8encodedkeyspec(keybytes);
privatekeyprivatek=keyfactory.generateprivate(pkcs8keyspec);
signaturesignature=signature.getinstance(signature_algorithm);
signature.initsign(privatek);
signature.update(parse2hexstr(data).getbytes(charset));

result=newbase64().encodetostring(signature.sign());
}catch(exceptione){
thrownewexception(e);
}
returnresult;
}

/**
*校驗數字簽名
*
*@paramdata已加密數據
*@parampublickey公鑰(base64編碼)
*@paramsign數字簽名
*@return
*@throwsexception
*/
publicbooleanverify(stringdata,stringpublickey,stringsign)throwsexception{
booleanresult;

try{
byte[]keybytes=newbase64().decode(publickey);
x509encodedkeyspeckeyspec=newx509encodedkeyspec(keybytes);
publickeypublick=keyfactory.generatepublic(keyspec);
signaturesignature=signature.getinstance(signature_algorithm);
signature.initverify(publick);
signature.update(parse2hexstr(data).getbytes(charset));
result=signature.verify(newbase64().decode(sign));
}catch(exceptione){
thrownewexception(e);
}
returnresult;
}

/**
*將二進制轉換成16進制
*
*@paramdata
*@return
*/
(stringdata)throwsexception{
stringresult="";
try{
byte[]buf=data.getbytes(charset);

stringbuffersb=newstringbuffer();
for(inti=0;istringhex=integer.tohexstring(buf[i]&0xff);
if(hex.length()==1){
hex='0' hex;
}
sb.append(hex.touppercase());
}
result=sb.tostring();
}catch(unsupportedencodingexceptione){
thrownewexception(e);
}
returnresult;
}

/**
*生成公鑰與私鑰
*/
publicstaticvoidcreatekey()throwsexception{
try{
=keypairgenerator.getinstance(algorithm);
keypairgenerator.initialize(key_size);
keypairkeypair=keypairgenerator.generatekeypair();
rsapublickeyrsapublickey=(rsapublickey)keypair.getpublic();
rsaprivatekeyrsaprivatekey=(rsaprivatekey)keypair.getprivate();

stringpublickey=base64.encodebase64string(rsapublickey.getencoded());
stringprivatekey=base64.encodebase64string(rsaprivatekey.getencoded());

system.out.println("publickey=" publickey " privatekey=" privatekey);
}catch(nosuchalgorithmexceptione){
thrownewexception(e);
}
}

publicstaticvoidmain(string[]args)throwsexception{

stringprivate_key=" m /fns1bmgfjhi8lhr/o/hy8efb/i/ddylcccu4bcltxpki8edc kjr2wvyyfnvmwee// w5c leseoaqdo5nahrzsl8bidoxten2j dsa///1qx t8f5wd8i/8gu702pecwkgi5ymrarq / /nkeftq0snpudvbgxvpji9/fouf";
stringpublic_key=" lc///nfovkvqndzdh60dzlgomde0nbrtn/5zejgwjbvdlvcfoihwidaqab";

rsautilsrsautil=newrsautils();
stringencryptbypublickey=rsautil.encryptbypublickey("你好!",public_key);
system.out.println(encryptbypublickey);
stringdecryptbyprivatekey=rsautil.decryptbyprivatekey(encryptbypublickey,private_key);
system.out.println(decryptbyprivatekey);
stringencryptbyprivatekey=rsautil.encryptbyprivatekey("你好!",private_key);
system.out.println(encryptbyprivatekey);
stringdecryptbypublickey=rsautil.decryptbypublickey(encryptbyprivatekey,public_key);
system.out.println(decryptbypublickey);
stringsign=rsautil.sign("1234",private_key);
system.out.println("sign:" sign);
system.out.println(rsautil.verify("1234",public_key,sign));
}
}

㈥ 求救求救。。。剛學習java,有沒有java的rsa完整演算法急。。。

例如:import java.awt.*;
即把java包中awt組件包中所有的類添加進來了,類似的,你要指定某個類就要指定到他的具體位置,可以在類所在的文件包上用「*」,後者吧「*」換成制定的類名;
不知道回答的是否你想要的,希望會對你有幫助!努力加油!

㈦ 求rsa演算法java實現源代碼(帶界面的)

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: [email protected]
* msn:[email protected]
* @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 molus
* @param publicexponent
* @return rsapublickey
* @throws encryptexception
*/
public static rsapublickey generatersapublickey(byte[] molus, 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(molus), new biginteger(publicexponent));
try {
return (rsapublickey) keyfac.generatepublic(pubkeyspec);
} catch (invalidkeyspecexception ex) {
throw new encryptexception(ex.getmessage());
}
}
/**
* 生成私鑰
* @param molus
* @param privateexponent
* @return rsaprivatekey
* @throws encryptexception
*/
public static rsaprivatekey generatersaprivatekey(byte[] molus, 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(molus), 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 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 encryptexception(e.getmessage());
}
}
/**
*
* @param args
* @throws exception
*/
public static void main(string[] args) throws exception {
file file = new file("test.html");
fileinputstream in = new fileinputstream(file);
bytearrayoutputstream bout = new bytearrayoutputstream();
byte[] tmpbuf = new byte[1024];
int count = 0;
while ((count = in.read(tmpbuf)) != -1) {
bout.write(tmpbuf, 0, count);
tmpbuf = new byte[1024];
}
in.close();
byte[] orgdata = bout.tobytearray();
keypair keypair = rsautil.generatekeypair();
rsapublickey pubkey = (rsapublickey) keypair.getpublic();
rsaprivatekey prikey = (rsaprivatekey) keypair.getprivate();

byte[] pubmodbytes = pubkey.getmolus().tobytearray();
byte[] pubpubexpbytes = pubkey.getpublicexponent().tobytearray();
byte[] primodbytes = prikey.getmolus().tobytearray();
byte[] pripriexpbytes = prikey.getprivateexponent().tobytearray();
rsapublickey recoverypubkey = rsautil.generatersapublickey(pubmodbytes,pubpubexpbytes);
rsaprivatekey recoveryprikey = rsautil.generatersaprivatekey(primodbytes,pripriexpbytes);

byte[] raw = rsautil.encrypt(prikey, orgdata);
file = new file("encrypt_result.dat");
outputstream out = new fileoutputstream(file);
out.write(raw);
out.close();
byte[] data = rsautil.decrypt(recoverypubkey, raw);
file = new file("decrypt_result.html");
out = new fileoutputstream(file);
out.write(data);
out.flush();
out.close();
}
}

http://book.77169.org/data/web5409/20050328/20050328__3830259.html

這個行吧
http://soft.zdnet.com.cn/software_zone/2007/0925/523319.shtml

再參考這個吧
http://topic.csdn.net/t/20040427/20/3014655.html

熱點內容
matlab命令窗口和新建腳本 發布:2024-07-17 15:51:26 瀏覽:374
建ftp文件夾 發布:2024-07-17 15:51:26 瀏覽:954
魔獸撿物腳本 發布:2024-07-17 15:27:56 瀏覽:129
開發ip伺服器 發布:2024-07-17 15:24:42 瀏覽:387
安卓系統視頻製作哪個好用 發布:2024-07-17 15:10:47 瀏覽:210
androidapk結構 發布:2024-07-17 15:10:43 瀏覽:945
c語言指針的例子 發布:2024-07-17 15:08:01 瀏覽:768
linuxzcat 發布:2024-07-17 15:02:09 瀏覽:901
賓士編程嗎 發布:2024-07-17 14:57:08 瀏覽:853
硬碟加密硬體 發布:2024-07-17 14:51:05 瀏覽:836
网站地图