當前位置:首頁 » 編程語言 » java公鑰加密

java公鑰加密

發布時間: 2024-06-25 18:58:23

java ibm jdk rsa 怎麼 加密

android和java webservice RSA處理的不同

1.andorid機器上生成的(密鑰對由伺服器在windows xp下生成並將公鑰發給客戶端保存)密碼無法在伺服器通過私鑰解密。

2.為了測試,在伺服器本地加解密正常,另外,在android上加解密也正常,但是在伺服器中加密(使用相同公鑰)後的密碼同樣無法在android系統解密(使用相同私鑰)。
3.由於對RSA加密演算法不了解,而且對Java RSA的加密過程也不清楚、谷歌一番,才了解到可能是加密過程中的填充字元長度不同,這跟加解密時指定的RSA演算法有關系。
4. 比如,在A機中使用標准RSA通過公鑰加密,然後在B系統中使用「RSA/ECB/NoPadding」使用私鑰解密,結果可以解密,但是會發現解密後的原文前面帶有很多特殊字元,這就是在加密前填充的空字元;如果在B系統中仍然使用標準的RSA演算法解密,這在相同類型的JDK虛擬機環境下當然是完全一樣的,關鍵是android系統使用的虛擬機(dalvik)跟SUN標准JDK是有所區別的,其中他們默認的RSA實現就不同。
5.更形象一點,在加密的時候加密的原文「abc」,直接使用「abc」.getBytes()方法獲得的bytes長度可能只有3,但是系統卻先把它放到一個512位的byte數組里,new byte[512],再進行加密。但是解密的時候使用的是「加密後的密碼」.getBytes()來解密,解密後的原文自然就是512長度的數據,即是在「abc」之外另外填充了500多位元組的其他空字元。

② 如何使用16進制編碼的RSA公鑰進行RSA加密

我們來回顧一下RSA的加密演算法。我們從公鑰加密演算法和簽名演算法的定義出發,用比較規范的語言來描述這一演算法。RSA公鑰加密體制包含如下3個演算法:KeyGen(密鑰生成演算法),Encrypt(加密演算法)以及Decrypt(解密演算法)。(PK,SK)\leftarrowKeyGen(\lambda)。密鑰生成演算法以安全常數\lambda作為輸入,輸出一個公鑰PK,和一個私鑰SK。安全常數用於確定這個加密演算法的安全性有多高,一般以加密演算法使用的質數p的大小有關。\lambda越大,質數p一般越大,保證體制有更高的安全性。在RSA中,密鑰生成演算法如下:演算法首先隨機產生兩個不同大質數p和q,計算N=pq。隨後,演算法計算歐拉函數\varphi(N)=(p-1)(q-1)。接下來,演算法隨機選擇一個小於\varphi(N)的整數e,並計算e關於\varphi(N)的模反元素d。最後,公鑰為PK=(N,e),私鑰為SK=(N,d)。CT\leftarrowEncrypt(PK,M)。加密演算法以公鑰PK和待加密的消息M作為輸入,輸出密文CT。在RSA中,加密演算法如下:演算法直接輸出密文為CT=M^e\mod\varphi(N)M\leftarrowDecrypt(SK,CT)。解密演算法以私鑰SK和密文CT作為輸入,輸出消息M。在RSA中,解密演算法如下:演算法直接輸出明文為M=CT^d\mod\varphi(N)。由於e和d在\varphi(N)下互逆,因此我們有:CT^d=M^{ed}=M\mod\varphi(N)所以,從演算法描述中我們也可以看出:公鑰用於對數據進行加密,私鑰用於對數據進行解密。當然了,這個也可以很直觀的理解:公鑰就是公開的密鑰,其公開了大家才能用它來加密數據。私鑰是私有的密鑰,誰有這個密鑰才能夠解密密文。否則大家都能看到私鑰,就都能解密,那不就亂套了。=================分割線=================我們再來回顧一下RSA簽名體制。簽名體制同樣包含3個演算法:KeyGen(密鑰生成演算法),Sign(簽名演算法),Verify(驗證演算法)。(PK,SK)\leftarrowKeyGen(\lambda)。密鑰生成演算法同樣以安全常數\lambda作為輸入,輸出一個公鑰PK和一個私鑰SK。在RSA簽名中,密鑰生成演算法與加密演算法完全相同。\sigma\leftarrowSign(SK,M)。簽名演算法以私鑰SK和待簽名的消息M作為輸入,輸出簽名\sigma。在RSA簽名中,簽名演算法直接輸出簽名為\sigma=M^d\mod\varphi(N)。注意,簽名演算法和RSA加密體制中的解密演算法非常像。b\leftarrowVerify(PK,\sigma,M)。驗證演算法以公鑰PK,簽名\sigma以及消息M作為輸入,輸出一個比特值b。b=1意味著驗證通過。b=0意味著驗證不通過。在RSA簽名中,驗證演算法首先計算M'=\sigma^e\mod\varphi(N),隨後對比M'與M,如果相等,則輸出b=1,否則輸出b=0。注意:驗證演算法和RSA加密體制中的加密演算法非常像。所以,在簽名演算法中,私鑰用於對數據進行簽名,公鑰用於對簽名進行驗證。這也可以直觀地進行理解:對一個文件簽名,當然要用私鑰,因為我們希望只有自己才能完成簽字。驗證過程當然希望所有人都能夠執行,大家看到簽名都能通過驗證證明確實是我自己簽的。=================分割線=================那麼,為什麼題主問這么一個問題呢?我們可以看到,RSA的加密/驗證,解密/簽字過程太像了。同時,RSA體制本身就是對稱的:如果我們反過來把e看成私鑰,d看成公鑰,這個體制也能很好的執行。我想正是由於這個原因,題主在學習RSA體制的時候才會出現這種混亂。那麼解決方法是什麼呢?建議題主可以學習一下其他的公鑰加密體制以及簽名體制。其他的體制是沒有這種對稱性質的。舉例來說,公鑰加密體制的話可以看一看ElGamal加密,以及更安全的Cramer-Shoup加密。簽名體制的話可以進一步看看ElGamal簽名,甚至是BLS簽名,這些體制可能能夠幫助題主更好的弄清加密和簽名之間的區別和潛在的聯系。至於題主問的加密和簽名是怎麼結合的。這種體制叫做簽密方案(SignCrypt),RSA中,這種簽密方案看起來特別特別像,很容易引起混亂。在此我不太想詳細介紹RSA中的加密與簽字結合的方案。我想提醒題主的是,加密與簽字結合時,兩套公私鑰是不同的。

③ 高分求java的RSA 和IDEA 加密解密演算法

RSA演算法非常簡單,概述如下:
找兩素數p和q
取n=p*q
取t=(p-1)*(q-1)
取任何一個數e,要求滿足e<t並且e與t互素(就是最大公因數為1)
取d*e%t==1

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

設消息為數M (M <n)
設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<t並且e和t互素
用perl簡單窮舉可以獲得滿主 e*d%t ==1的數d:
C:\Temp>perl -e "foreach $i (1..9999){ print($i),last if $i*63%2668==1 }"
847
即d=847

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

取消息M=244我們看看

加密:

c=M**d%n = 244**847%2773
用perl的大數計算來算一下:
C:\Temp>perl -Mbigint -e "print 244**847%2773"
465
即用d對M加密後獲得加密信息c=465

解密:

我們可以用e來對加密後的c進行解密,還原M:
m=c**e%n=465**63%2773 :
C:\Temp>perl -Mbigint -e "print 465**63%2773"
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 "%03X",$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 <tt>base</tt>^<sup><tt>pow</tt></sup> within the molar
* domain of <tt>mod</tt>.
*
* @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 <tt>base</tt>^<sup><tt>pow</tt></sup> within the molar
* domain of <tt>mod</tt>.
*/
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/

④ Java RSA 加密解密中 密鑰保存並讀取,數據加密解密並保存讀取 問題

幫你完善了下代碼。

importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.FileReader;
importjava.io.OutputStream;
importjava.io.PrintWriter;
importjava.io.Reader;
importjava.util.Map;

publicclassTest{
staticStringpublicKey;
staticStringprivateKey;

publicTest()throwsException{
//TODOAuto-generatedconstructorstub
Map<String,Object>keyMap=RSAUtils.genKeyPair();
publicKey=RSAUtils.getPublicKey(keyMap);
privateKey=RSAUtils.getPrivateKey(keyMap);

//保存密鑰,名字分別為publicKey。txt和privateKey。txt;
PrintWriterpw1=newPrintWriter(newFileOutputStream(
"D:/publicKey.txt"));
PrintWriterpw2=newPrintWriter(newFileOutputStream(
"D:/privateKey.txt"));
pw1.print(publicKey);
pw2.print(privateKey);
pw1.close();
pw2.close();

//從保存的目錄讀取剛才的保存的公鑰,
Stringpubkey=readFile("D:/publicKey.txt");//讀取的公鑰內容;
Stringdata=readFile("D:/1.txt");//需要公鑰加密的文件的內容(如D:/1.txt)
byte[]encByPubKeyData=RSAUtils.encryptByPublicKey(data.getBytes(),
pubkey);
//將加密數據base64後寫入文件
writeFile("D:/Encfile.txt",Base64Utils.encode(encByPubKeyData).getBytes("UTF-8"));
//加密後的文件保存在

Stringprikey=readFile("D:/privateKey.txt");//從保存的目錄讀取剛才的保存的私鑰,
StringEncdata=readFile("D:/Encfile.txt");//剛才加密的文件的內容;
byte[]encData=Base64Utils.decode(Encdata);
byte[]decByPriKeyData=RSAUtils.decryptByPrivateKey(encData,prikey);
//解密後後的文件保存在D:/Decfile.txt
writeFile("D:/Decfile.txt",decByPriKeyData);
}

privatestaticStringreadFile(StringfilePath)throwsException{
FileinFile=newFile(filePath);
longfileLen=inFile.length();
Readerreader=newFileReader(inFile);

char[]content=newchar[(int)fileLen];
reader.read(content);
System.out.println("讀取到的內容為:"+newString(content));
returnnewString(content);
}

privatestaticvoidwriteFile(StringfilePath,byte[]content)
throwsException{
System.out.println("待寫入文件的內容為:"+newString(content));
FileoutFile=newFile(filePath);
OutputStreamout=newFileOutputStream(outFile);
out.write(content);
if(out!=null)out.close();
}

publicstaticvoidmain(String[]args)throwsException{
//TODOAuto-generatedmethodstub

newTest();
}

}

測試結果:

讀取到的內容為:++lXfZxzNpeA+rHaxmeQ2qI+5ES9AF7G6KIwjzakKsA08Ly+1y3dp0BnoyHF7/Pj3AS28fDmE5piea7w36vp4E3Ts+F9vwIDAQAB
讀取到的內容為:鍩縣ahaha

⑤ Java編程如何給數字加密

最簡單的,用異或運算。
你也可以自己寫個加密方法啊。
比如說:利用unicode字元加密啊。假設一個數字a它的unicode值是1234,你自己設計個函數,比如說y=2x^3+3,得到一個新的unicode字元,然後把這個unicode字元轉換為字母,這個字母可能是漢字,但更可能是外國符文,反正一般人不會認出來的。你解密的時候,倒推一下就行了。

⑥ Java鐢熸垚RSA闈炲圭О鍨嬪姞瀵嗙殑鍏閽ュ拰縐侀掗

銆銆闈炲圭О鍨嬪姞瀵嗛潪甯擱傚悎澶氫釜瀹㈡埛絝鍜屾湇鍔″櫒涔嬮棿鐨勭樺瘑閫氳 瀹㈡埛絝浣跨敤鍚屼竴涓鍏閽ュ皢鏄庢枃鍔犲瘑 鑰岃繖涓鍏閽ヤ笉鑳介嗗悜鐨勮В瀵 瀵嗘枃鍙戦佸埌鏈嶅姟鍣ㄥ悗鏈夋湇鍔″櫒絝鐢ㄧ侀掗瑙e瘑 榪欐牱灝卞仛鍒頒簡鏄庢枃鐨勫姞瀵嗕紶閫

銆銆闈炲圭О鍨嬪姞瀵嗕篃鏈夊畠鍏堝ぉ鐨勭己鐐 鍔犲瘑 瑙e瘑閫熷害鎱㈠埗綰︿簡瀹冪殑鍙戞尌 濡傛灉浣犳湁澶ч噺鐨勬枃瀛楅渶瑕佸姞瀵嗕紶閫 寤鴻浣犻氳繃闈炲圭О鍨嬪姞瀵嗘潵鎶婂圭О鍨 瀵嗛掗 鍒嗗彂鍒板㈡埛絝 鍙婃椂鏇存柊瀵圭О鍨 瀵嗛掗

銆銆import java io *;

銆銆import java security *;

銆銆import javax crypto *;

銆銆import javax crypto spec *;

銆銆/**

銆銆* <p>Title: RSA闈炲圭О鍨嬪姞瀵嗙殑鍏閽ュ拰縐侀掗</p>

銆銆* <p>Description: </p>

銆銆* <p>Copyright: Copyright (c) </p>

銆銆* <p>Company: </p>

銆銆* @author not attributable

銆銆* @version

銆銆*/

銆銆public class KeyRSA {

銆銆private KeyPairGenerator kpg = null;

銆銆private KeyPair kp = null;

銆銆private PublicKey public_key = null;

銆銆private PrivateKey private_key = null;

銆銆private FileOutputStream public_file_out = null;

銆銆private ObjectOutputStream public_object_out = null;

銆銆private FileOutputStream private_file_out = null;

銆銆private ObjectOutputStream private_object_out = null;

銆銆/**

銆銆* 鏋勯犲嚱鏁

銆銆* @param in 鎸囧畾瀵嗗寵闀垮害錛堝彇鍊艱寖鍥 鍀 錛

銆銆* @throws NoSuchAlgorithmException 寮傚父

銆銆*/

銆銆public KeyRSA(int in String address) throws NoSuchAlgorithmException FileNotFoundException IOException

銆銆{

銆銆kpg = KeyPairGenerator getInstance( RSA ); //鍒涘緩 瀵嗗寵瀵 鐢熸垚鍣

銆銆kpg initialize(in); //鎸囧畾瀵嗗寵闀垮害錛堝彇鍊艱寖鍥 鍀 錛

銆銆kp = kpg genKeyPair(); //鐢熸垚 瀵嗗寵瀵 鍏朵腑鍖呭惈鐫涓涓鍏鍖欏拰涓涓縐佸寵鐨勪俊鎮

銆銆public_key = kp getPublic(); //鑾峰緱鍏鍖

銆銆private_key = kp getPrivate(); //鑾峰緱縐佸寵

銆銆//淇濆瓨鍏鍖

銆銆public_file_out = new FileOutputStream(address + /public_key dat );

銆銆public_object_out = new ObjectOutputStream(public_file_out);

銆銆public_object_out writeObject(public_key);

銆銆//淇濆瓨縐佸寵

銆銆private_file_out = new FileOutputStream(address + /private_key dat );

銆銆private_object_out = new ObjectOutputStream(private_file_out);

銆銆private_object_out writeObject(private_key);

銆銆}

銆銆public static void main(String[] args) {

銆銆try {

銆銆System out println( 縐佸寵鍜屽叕鍖欎繚瀛樺埌C鐩樹笅鐨勬枃浠朵腑 );

銆銆new KeyRSA( c:/ );

銆銆}

銆銆catch (IOException ex) {

銆銆}

銆銆catch (NoSuchAlgorithmException ex) {

銆銆}

銆銆}

lishixin/Article/program/Java/hx/201311/26592

⑦ 如何用java語言對即時通訊軟體進行加密

一、Java軟體加密基本思路
對於應用軟體的保護筆者從兩個方面進行考慮,第一是阻止盜版使用軟體,第二是阻止競爭對手對軟體反編譯,即阻止對軟體的逆向工程。
1、阻止盜版
在軟體運行時對自身存在的合法性進行判斷,如果認為自身的存在和運行是被授權的、合法的,就運行;否則終止運行。這樣即使軟體可以被隨意復制,只要盜版用戶沒有相應的授權信息就無法使用軟體。
2、阻止反編譯
對編譯產生的Class文件加密處理,並在運行時進行解密,解密者無法對軟體進行反編譯。
二、Java軟體加密的總體流程
為了保護用Java語言開發的軟體,我們設計並實現了一個實用、高強度的加密演算法。以下稱需要保護的Java軟體為「受保護程序」,稱對「受保護程序」進行加密保護的軟體為「加密程序」。對軟體加密保護的流程如圖1所示。

三、加密演算法分析設計
1、用戶信息提取器設計
為了防止用戶發布序列號而導致「一次發行,到處都是」的盜版問題,提取用戶機器中硬體相關的、具有唯一性的信息——用戶計算機的硬碟分區C的序列號,並要求用戶將此信息與用戶名一起返回,之後用「序列號生成器」根據用戶返回信息生成一個唯一合法的軟體注冊序列號發回用戶,用戶即可使用此號碼注冊使用軟體。
這個信息提取器使用Winclows 32匯編以一個獨立的小程序方式實現,程序代碼如圖2所示。

2、序列號生成器與序列號合法性判斷函數的設計
序列號生成器與序列號合法性判斷函數中運用RSA加密演算法。在序列號生成器中是使用私鑰將用戶返回的信息(硬碟序列號,用戶名)進行加密得到相應的注冊序列號;在序列號合法性判斷函數中使用私鑰將用戶輸入的注冊序列號解密,再與(硬碟序列號,用戶名)進行比較,一致則調用程序裝載器將程序其他部分解密裝入內存,初始化刪環境並運行程序主體;否則退出。
RSA加密演算法的實現需要使用大數運算庫,我們使用MIRACL大數庫來實現RSA計算,序列號生成器的主要代碼如下:
char szlnputString[]=」機器碼和用戶名組成的字元串」;
char szSerial[256]=[0];//用於存放生成的注冊碼
bign,d,c,m; //MIRACL中的大數類型
mip→IBASE=16; //以16進制模式
n= mlrvar(0); //初始化大數
d= mirvar(0);
c= mirvar(0); //C存放輸入的字元串大數
m= mlrva(o);
bytes to big( len, szlnputString,c);
//將輸入字元串轉換成大數形式並存入變數c中
cinstr(n,」以字元串形成表示的模數」);//初始化模數
cinstr(d,」以字元串形成表示的公鑰」)://初始化公鑰
powmod(c,d,n,m); //計算m=cdmod n
cotstr(m,szSerial);//m的16進制字元串即為注冊碼
序列號合法性檢測函數的主要代碼如下:
char szlnputStringL]=」機器碼和用戶名組成的字元串」;
char szSerial[ 256]=」用戶輸入的序列號」
bign,e,c,m; //MIRACL中的大數類型
mip→IBASE=16; //以16進制模式
cinstr(m,szSerial); //將序列號的16進制轉成大數形式
cinstr(n,」模數n的字元串形式」);//初始化模數n
cinstr(e,」字元串形式的公鑰」);//初始化公鑰
if compare(m,n)==-1) //m<n時才進行解密
{
powmod(m,e,n,c);//計算m=me mod n
big_to _bytes(0,c,szSerial,0); //轉為字元串
return lstrcmp( szlnputString,szSerial);
}
3、強耦合關系的設計
如果在序列號合法性檢測函數中簡單地使用圖3所示流程:

解密者可以使用以下幾種手段進行攻擊:
(1)修改「判斷合法性子函數」的返回指令,讓它永遠返回正確值,這樣可以使用任意的序列號,安裝/使用軟體。
(2)修改判斷後的跳轉指令,使程序永遠跳到正確的分支運行,效果和上一種一樣。
(3)在「判斷合法性子函數」之前執行一條跳轉指令,繞過判斷,直接跳轉到「正常執行」分支運行,這樣可以不用輸入序列號安裝/使用軟體。
為阻止以上攻擊手段,筆者在程序中增加了「序列號合法性檢測函數」與程序其他部分「強耦合」(即增強其與程序其他部分的關聯度,成為程序整體密不可分的一部分,一旦被修改程序將無法正常工作)的要求(見圖1),並且設置一個「完整性檢測函數」用於判斷相關的代碼是否被修改過。當然,基於同樣的原因,「完整性檢測函數」也必須與程序其他部分存在「強耦合」關系。
強耦合關系通過以下方式建立:
在程序其他部分的函數(例如函數A)中隨機的訪問需要強耦合的「序列號合法性檢測函數」和「完整性檢測函數」,在調用時隨機的選擇使用一個錯誤的序列號或是用戶輸入的序列號,並根據返回結果選擇執行A中正常的功能代碼還是錯誤退出的功能代碼,流程如圖4所示。

經過這種改進,如果破解者通過修改代碼的方式破解將因「完整性檢測」失敗導致程序退出;如果使用SMC等技術繞過「序列號合法性判斷函數」而直接跳至序列號正確時的執行入口,在後續的運行中,將因為隨機的耦合調用失敗導致程序退出。破解者要破解軟體將不得不跟蹤所有進行了耦合調用的函數,這顯然是一個艱巨的任務。
4、完整性檢測函數的設計
我們使用CRC演算法算出需進行完整性檢測的文件的校驗碼,並用RSA加密演算法的公鑰(不同於序列號合法性檢測中的公鑰/私鑰對)將其加密存放在特定的文件中,在檢測時先用CRC演算法重新生成需進行完
整性檢測的文件的校驗碼,並用私鑰將保存的校驗碼解密,兩者相比較,相等則正常運行;否則退出。
5、程序載入器的設計
與編譯成機器碼執行的程序不同,Java程序只能由Java虛擬機解釋執行,因此程序載入器的工作包括:初始化Java虛擬機;在內存中解密當前要運行的class文件;使解密後的c:lass文件在虛擬機中運行,在
需要時解密另一個class文件。圖5是用於初始化JVM的代碼:

以上介紹了我們設計的針對Java軟體的加密保護方法,其中綜合運用了多種加密技術,抗破解強度高;使用純軟體保護技術,成本低。經筆者在Windows系列平台上進行測試,運行穩定,效果良好。
在研宄開發過程中,我們還總結出加密保護軟體的一些經驗:
1、對關鍵代碼和數據要靜態加密,再動態解密執行;要結合具體的工作平台使用反跟蹤/調試技術;
2、要充分利用系統的功能,如在Windows下使用DLL文件或驅動程序形式能得到最大的豐又限,可以充分利用系統具有的各種功能;
3、如果可能應該將關鍵代碼存放在不可禚復制的地方;
4、序列號要與機器碼等用戶信息相關以阻止鹽復布序列號;
5、加密流程的合理性比加密演算法本身的強度更重要。

⑧ 如何用JAVA實現字元串簡單加密解密

java加密字元串可以使用des加密演算法,實例如下:
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/**
* 加密解密
*
* @author shy.qiu
* @since http://blog.csdn.net/qiushyfm
*/
public class CryptTest {
/**
* 進行MD5加密
*
* @param info
* 要加密的信息
* @return String 加密後的字元串
*/
public String encryptToMD5(String info) {
byte[] digesta = null;
try {
// 得到一個md5的消息摘要
MessageDigest alga = MessageDigest.getInstance("MD5");
// 添加要進行計算摘要的信息
alga.update(info.getBytes());
// 得到該摘要
digesta = alga.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將摘要轉為字元串
String rs = byte2hex(digesta);
return rs;
}
/**
* 進行SHA加密
*
* @param info
* 要加密的信息
* @return String 加密後的字元串
*/
public String encryptToSHA(String info) {
byte[] digesta = null;
try {
// 得到一個SHA-1的消息摘要
MessageDigest alga = MessageDigest.getInstance("SHA-1");
// 添加要進行計算摘要的信息
alga.update(info.getBytes());
// 得到該摘要
digesta = alga.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將摘要轉為字元串
String rs = byte2hex(digesta);
return rs;
}
// //////////////////////////////////////////////////////////////////////////
/**
* 創建密匙
*
* @param algorithm
* 加密演算法,可用 DES,DESede,Blowfish
* @return SecretKey 秘密(對稱)密鑰
*/
public SecretKey createSecretKey(String algorithm) {
// 聲明KeyGenerator對象
KeyGenerator keygen;
// 聲明 密鑰對象
SecretKey deskey = null;
try {
// 返回生成指定演算法的秘密密鑰的 KeyGenerator 對象
keygen = KeyGenerator.getInstance(algorithm);
// 生成一個密鑰
deskey = keygen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 返回密匙
return deskey;
}
/**
* 根據密匙進行DES加密
*
* @param key
* 密匙
* @param info
* 要加密的信息
* @return String 加密後的信息
*/
public String encryptToDES(SecretKey key, String info) {
// 定義 加密演算法,可用 DES,DESede,Blowfish
String Algorithm = "DES";
// 加密隨機數生成器 (RNG),(可以不寫)
SecureRandom sr = new SecureRandom();
// 定義要生成的密文
byte[] cipherByte = null;
try {
// 得到加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密鑰和模式初始化Cipher對象
// 參數:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
c1.init(Cipher.ENCRYPT_MODE, key, sr);
// 對要加密的內容進行編碼處理,
cipherByte = c1.doFinal(info.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
// 返回密文的十六進制形式
return byte2hex(cipherByte);
}
/**
* 根據密匙進行DES解密
*
* @param key
* 密匙
* @param sInfo
* 要解密的密文
* @return String 返回解密後信息
*/
public String decryptByDES(SecretKey key, String sInfo) {
// 定義 加密演算法,
String Algorithm = "DES";
// 加密隨機數生成器 (RNG)
SecureRandom sr = new SecureRandom();
byte[] cipherByte = null;
try {
// 得到加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密鑰和模式初始化Cipher對象
c1.init(Cipher.DECRYPT_MODE, key, sr);
// 對要解密的內容進行編碼處理
cipherByte = c1.doFinal(hex2byte(sInfo));
} catch (Exception e) {
e.printStackTrace();
}
// return byte2hex(cipherByte);
return new String(cipherByte);
}
// /////////////////////////////////////////////////////////////////////////////
/**
* 創建密匙組,並將公匙,私匙放入到指定文件中
*
* 默認放入mykeys.bat文件中
*/
public void createPairKey() {
try {
// 根據特定的演算法一個密鑰對生成器
KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");
// 加密隨機數生成器 (RNG)
SecureRandom random = new SecureRandom();
// 重新設置此隨機對象的種子
random.setSeed(1000);
// 使用給定的隨機源(和默認的參數集合)初始化確定密鑰大小的密鑰對生成器
keygen.initialize(512, random);// keygen.initialize(512);
// 生成密鑰組
KeyPair keys = keygen.generateKeyPair();
// 得到公匙
PublicKey pubkey = keys.getPublic();
// 得到私匙
PrivateKey prikey = keys.getPrivate();
// 將公匙私匙寫入到文件當中
doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 利用私匙對信息進行簽名 把簽名後的信息放入到指定的文件中
*
* @param info
* 要簽名的信息
* @param signfile
* 存入的文件
*/
public void signToInfo(String info, String signfile) {
// 從文件當中讀取私匙
PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);
// 從文件中讀取公匙
PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);
try {
// Signature 對象可用來生成和驗證數字簽名
Signature signet = Signature.getInstance("DSA");
// 初始化簽署簽名的私鑰
signet.initSign(myprikey);
// 更新要由位元組簽名或驗證的數據
signet.update(info.getBytes());
// 簽署或驗證所有更新位元組的簽名,返回簽名
byte[] signed = signet.sign();
// 將數字簽名,公匙,信息放入文件中
doObjToFile(signfile, new Object[] { signed, mypubkey, info });
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 讀取數字簽名文件 根據公匙,簽名,信息驗證信息的合法性
*
* @return true 驗證成功 false 驗證失敗
*/
public boolean validateSign(String signfile) {
// 讀取公匙
PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);
// 讀取簽名
byte[] signed = (byte[]) getObjFromFile(signfile, 1);
// 讀取信息
String info = (String) getObjFromFile(signfile, 3);
try {
// 初始一個Signature對象,並用公鑰和簽名進行驗證
Signature signetcheck = Signature.getInstance("DSA");
// 初始化驗證簽名的公鑰
signetcheck.initVerify(mypubkey);
// 使用指定的 byte 數組更新要簽名或驗證的數據
signetcheck.update(info.getBytes());
System.out.println(info);
// 驗證傳入的簽名
return signetcheck.verify(signed);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將二進制轉化為16進制字元串
*
* @param b
* 二進制位元組數組
* @return String
*/
public String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
/**
* 十六進制字元串轉化為2進制
*
* @param hex
* @return
*/
public byte[] hex2byte(String hex) {
byte[] ret = new byte[8];
byte[] tmp = hex.getBytes();
for (int i = 0; i < 8; i++) {
ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
}
return ret;
}
/**
* 將兩個ASCII字元合成一個位元組; 如:"EF"--> 0xEF
*
* @param src0
* byte
* @param src1
* byte
* @return byte
*/
public static byte uniteBytes(byte src0, byte src1) {
byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
.byteValue();
_b0 = (byte) (_b0 << 4);
byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
.byteValue();
byte ret = (byte) (_b0 ^ _b1);
return ret;
}
/**
* 將指定的對象寫入指定的文件
*
* @param file
* 指定寫入的文件
* @param objs
* 要寫入的對象
*/
public void doObjToFile(String file, Object[] objs) {
ObjectOutputStream oos = null;
try {
FileOutputStream fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
for (int i = 0; i < objs.length; i++) {
oos.writeObject(objs[i]);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 返回在文件中指定位置的對象
*
* @param file
* 指定的文件
* @param i
* 從1開始
* @return
*/
public Object getObjFromFile(String file, int i) {
ObjectInputStream ois = null;
Object obj = null;
try {
FileInputStream fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
for (int j = 0; j < i; j++) {
obj = ois.readObject();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return obj;
}
/**
* 測試
*
* @param args
*/
public static void main(String[] args) {
CryptTest jiami = new CryptTest();
// 執行MD5加密"Hello world!"
System.out.println("Hello經過MD5:" + jiami.encryptToMD5("Hello"));
// 生成一個DES演算法的密匙
SecretKey key = jiami.createSecretKey("DES");
// 用密匙加密信息"Hello world!"
String str1 = jiami.encryptToDES(key, "Hello");
System.out.println("使用des加密信息Hello為:" + str1);
// 使用這個密匙解密
String str2 = jiami.decryptByDES(key, str1);
System.out.println("解密後為:" + str2);
// 創建公匙和私匙
jiami.createPairKey();
// 對Hello world!使用私匙進行簽名
jiami.signToInfo("Hello", "mysign.bat");
// 利用公匙對簽名進行驗證。
if (jiami.validateSign("mysign.bat")) {
System.out.println("Success!");
} else {
System.out.println("Fail!");
}
}
}

熱點內容
python數組排序排序演算法 發布:2024-11-26 19:50:16 瀏覽:969
如保編程 發布:2024-11-26 19:29:58 瀏覽:812
我的世界手機版寶可夢生存多人伺服器 發布:2024-11-26 19:29:52 瀏覽:730
卡盟伺服器的象徵什麼意思 發布:2024-11-26 19:28:15 瀏覽:390
游戲平板安卓2000以下哪個好 發布:2024-11-26 19:21:12 瀏覽:547
php重命名文件夾 發布:2024-11-26 19:06:01 瀏覽:19
阿里雲ecs伺服器無法連接公網ip 發布:2024-11-26 19:01:32 瀏覽:43
java寫helloworld 發布:2024-11-26 19:00:56 瀏覽:90
c語言遞歸排列 發布:2024-11-26 18:50:55 瀏覽:449
密碼鎖為什麼不建議用南孚 發布:2024-11-26 18:45:00 瀏覽:154