導航:首頁 > 編程語言 > rsa加密演算法java

rsa加密演算法java

發布時間:2023-08-18 23:03:47

1. 如何用java實現128位密鑰的RSA演算法

importjavax.crypto.Cipher;
importsun.misc.BASE64Decoder;
importsun.misc.BASE64Encoder;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
importjava.security.Key;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.SecureRandom;

publicclassRSA_Encrypt{
/**指定加密演算法為DESede*/
privatestaticStringALGORITHM="RSA";
/**指定key的大小*/
privatestaticintKEYSIZE=128;
/**指定公鑰存放文件*/
privatestaticStringPUBLIC_KEY_FILE="PublicKey";
/**指定私鑰存放文件*/
privatestaticStringPRIVATE_KEY_FILE="PrivateKey";
//privatestaticStringPUBLIC_KEY_FILE="D://PublicKey.a";
//privatestaticStringPRIVATE_KEY_FILE="D://PrivateKey.a";


/**
*生成密鑰對
*/
()throwsException{
/**RSA演算法要求有一個可信任的隨機數源*/
SecureRandomsr=newSecureRandom();
/**為RSA演算法創建一個KeyPairGenerator對象*/
KeyPairGeneratorkpg=KeyPairGenerator.getInstance(ALGORITHM);
/**利用上面的隨機數據源初始化這個KeyPairGenerator對象*/
kpg.initialize(KEYSIZE,sr);
/**生成密匙對*/
KeyPairkp=kpg.generateKeyPair();
/**得到公鑰*/
KeypublicKey=kp.getPublic();
/**得到私鑰*/
KeyprivateKey=kp.getPrivate();
/**用對象流將生成的密鑰寫入文件*/
ObjectOutputStreamoos1=newObjectOutputStream(newFileOutputStream(PUBLIC_KEY_FILE));
ObjectOutputStreamoos2=newObjectOutputStream(newFileOutputStream(PRIVATE_KEY_FILE));
oos1.writeObject(publicKey);
oos2.writeObject(privateKey);
/**清空緩存,關閉文件輸出流*/
oos1.close();
oos2.close();
}
/**
*加密方法
*source:源數據
*/
publicstaticStringencrypt(Stringsource)throwsException{
generateKeyPair();
/**將文件中的公鑰對象讀出*/
ObjectInputStreamois=newObjectInputStream(newFileInputStream(PUBLIC_KEY_FILE));
Keykey=(Key)ois.readObject();
ois.close();
/**得到Cipher對象來實現對源數據的RSA加密*/
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[]b=source.getBytes();
/**執行加密操作*/
byte[]b1=cipher.doFinal(b);
BASE64Encoderencoder=newBASE64Encoder();
returnencoder.encode(b1);
}
/**
*解密演算法
*cryptograph:密文
*/
publicstaticStringdecrypt(Stringcryptograph)throwsException{
/**將文件中的私鑰對象讀出*/
ObjectInputStreamois=newObjectInputStream(newFileInputStream(PRIVATE_KEY_FILE));
Keykey=(Key)ois.readObject();
/**得到Cipher對象對已用公鑰加密的數據進行RSA解密*/
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,key);
BASE64Decoderdecoder=newBASE64Decoder();
byte[]b1=decoder.decodeBuffer(cryptograph);
/**執行解密操作*/
byte[]b=cipher.doFinal(b1);
returnnewString(b);
}

publicstaticvoidmain(String[]args){
try{
Stringsource="HelloWorld!";//要加密的字元串
Stringcryptograph=encrypt(source);
System.out.println(cryptograph);

Stringtarget=decrypt(cryptograph);//解密密文
System.out.println(target);
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}//生成的密文
}
}

2. JAVA寫RSA加密,公鑰私鑰都是一樣的,為什麼每次加密的結果不一樣

因為rsa是非對稱加密,它使用的是隨機大素數的抽取,每次隨機生成的,所以每次加密的結果不可能一樣

3. java rsa私鑰加密

java rsa私鑰加密是什麼?讓我們一起來了解一下吧!

java rsa私鑰加密是一種加密演算法。私鑰加密演算法是用私鑰來進行加密與解密信息。私鑰加密也被稱作對稱加密,原因是加密與解密使用的秘鑰是同一個。

RSA加密需要注意的事項如下:

1. 首先產生公鑰與私鑰

2. 設計加密與解密的演算法

3. 私鑰加密的數據信息只能由公鑰可以解密

4. 公鑰加密的數據信息只能由私鑰可以解密

實戰演練,具體步驟如下: public class RsaCryptTools {     private static final String CHARSET = "utf-8";     private static final Base64.Decoder decoder64 = Base64.getDecoder();     private static final Base64.Encoder encoder64 = Base64.getEncoder();       /**      * 生成公私鑰      * @param keySize      * @return      * @throws NoSuchAlgorithmException      */     public static SecretKey generateSecretKey(int keySize) throws NoSuchAlgorithmException {         //生成密鑰對         KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");         keyGen.initialize(keySize, new SecureRandom());         KeyPair pair = keyGen.generateKeyPair();         PrivateKey privateKey = pair.getPrivate();         PublicKey publicKey = pair.getPublic();         //這里可以將密鑰對保存到本地         return new SecretKey(encoder64.encodeToString(publicKey.getEncoded()), encoder64.encodeToString(privateKey.getEncoded()));     }     /**      * 私鑰加密      * @param data      * @param privateInfoStr      * @return      * @throws IOException      * @throws InvalidCipherTextException      */     public static String encryptData(String data, String privateInfoStr) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {           Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");         cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(privateInfoStr));         return encoder64.encodeToString(cipher.doFinal(data.getBytes(CHARSET)));     }       /**      * 公鑰解密      * @param data      * @param publicInfoStr      * @return      */     public static String decryptData(String data, String publicInfoStr) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {         byte[] encryptDataBytes=decoder64.decode(data.getBytes(CHARSET));         //解密         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");         cipher.init(Cipher.DECRYPT_MODE, getPublicKey(publicInfoStr));         return new String(cipher.doFinal(encryptDataBytes), CHARSET);     }     private static PublicKey getPublicKey(String base64PublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));         KeyFactory keyFactory = KeyFactory.getInstance("RSA");         return keyFactory.generatePublic(keySpec);     }     private static PrivateKey getPrivateKey(String base64PrivateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {         PrivateKey privateKey = null;         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes()));         KeyFactory keyFactory = null;         keyFactory = KeyFactory.getInstance("RSA");         privateKey = keyFactory.generatePrivate(keySpec);         return privateKey;     }       /**      * 密鑰實體      * @author hank      * @since 2020/2/28 0028 下午 16:27      */     public static class SecretKey {         /**          * 公鑰          */         private String publicKey;         /**          * 私鑰          */         private String privateKey;           public SecretKey(String publicKey, String privateKey) {             this.publicKey = publicKey;             this.privateKey = privateKey;         }           public String getPublicKey() {             return publicKey;         }           public void setPublicKey(String publicKey) {             this.publicKey = publicKey;         }           public String getPrivateKey() {             return privateKey;         }           public void setPrivateKey(String privateKey) {             this.privateKey = privateKey;         }           @Override         public String toString() {             return "SecretKey{" +                     "publicKey='" + publicKey + '\'' +                     ", privateKey='" + privateKey + '\'' +                     '}';         }     }       private static void writeToFile(String path, byte[] key) throws IOException {         File f = new File(path);         f.getParentFile().mkdirs();           try(FileOutputStream fos = new FileOutputStream(f)) {             fos.write(key);             fos.flush();         }     }       public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {         SecretKey secretKey = generateSecretKey(2048);         System.out.println(secretKey);         String enStr = encryptData("你好測試測試", secretKey.getPrivateKey());         System.out.println(enStr);         String deStr = decryptData(enStr, secretKey.getPublicKey());         System.out.println(deStr);         enStr = encryptData("你好測試測試hello", secretKey.getPrivateKey());         System.out.println(enStr);         deStr = decryptData(enStr, secretKey.getPublicKey());         System.out.println(deStr);     }   }

4. java RSA演算法實現256位密鑰怎麼做

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

5. java中的rsa\des演算法的方法

rsa加密解密演算法
1978年就出現了這種演算法,它是第一個既能用於數據加密
也能用於數字簽名的演算法。它易於理解和操作,也很流行。算
法的名字以發明者的名字命名:Ron Rivest, AdiShamir 和
Leonard Adleman。但RSA的安全性一直未能得到理論上的證明。

RSA的安全性依賴於大數分解。公鑰和私鑰都是兩個大素數
( 大於 100個十進制位)的函數。據猜測,從一個密鑰和密文
推斷出明文的難度等同於分解兩個大素數的積。

密鑰對的產生:選擇兩個大素數,p 和q 。計算:
n = p * q
然後隨機選擇加密密鑰e,要求 e 和 ( p - 1 ) * ( q - 1 )
互質。最後,利用Euclid 演算法計算解密密鑰d, 滿足

e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )

其中n和d也要互質。數e和
n是公鑰,d是私鑰。兩個素數p和q不再需要,應該丟棄,不要讓任
何人知道。 加密信息 m(二進製表示)時,首先把m分成等長數據
塊 m1 ,m2,..., mi ,塊長s,其中 2^s <= n, s 盡可能的大。對
應的密文是:

ci = mi^e ( mod n ) ( a )

解密時作如下計算:

mi = ci^d ( mod n ) ( b )

RSA 可用於數字簽名,方案是用 ( a ) 式簽名, ( b )
式驗證。具體操作時考慮到安全性和 m信息量較大等因素,一般是先
作 HASH 運算。

RSA 的安全性。
RSA的安全性依賴於大數分解,但是否等同於大數分解一直未能得到理
論上的證明,因為沒有證明破解RSA就一定需要作大數分解。假設存在
一種無須分解大數的演算法,那它肯定可以修改成為大數分解演算法。目前,
RSA的一些變種演算法已被證明等價於大數分解。不管怎樣,分解n是最顯
然的攻擊方法。現在,人們已能分解140多個十進制位的大素數。因此,
模數n必須選大一些,因具體適用情況而定。

RSA的速度:
由於進行的都是大數計算,使得RSA最快的情況也比DES慢上100倍,無論
是軟體還是硬體實現。速度一直是RSA的缺陷。一般來說只用於少量數據
加密。

RSA的選擇密文攻擊:
RSA在選擇密文攻擊面前很脆弱。一般攻擊者是將某一信息作一下偽裝
(Blind),讓擁有私鑰的實體簽署。然後,經過計算就可得到它所想要的信
息。實際上,攻擊利用的都是同一個弱點,即存在這樣一個事實:乘冪保
留了輸入的乘法結構:

( XM )^d = X^d *M^d mod n

前面已經提到,這個固有的問題來自於公鑰密碼系統的最有用的特徵
--每個人都能使用公鑰。但從演算法上無法解決這一問題,主要措施有
兩條:一條是採用好的公鑰協議,保證工作過程中實體不對其他實體
任意產生的信息解密,不對自己一無所知的信息簽名;另一條是決不
對陌生人送來的隨機文檔簽名,簽名時首先使用One-Way HashFunction
對文檔作HASH處理,或同時使用不同的簽名演算法。在中提到了幾種不
同類型的攻擊方法。

RSA的公共模數攻擊。
若系統中共有一個模數,只是不同的人擁有不同的e和d,系統將是危險
的。最普遍的情況是同一信息用不同的公鑰加密,這些公鑰共模而且互
質,那末該信息無需私鑰就可得到恢復。設P為信息明文,兩個加密密鑰
為e1和e2,公共模數是n,則:

C1 = P^e1 mod n

C2 = P^e2 mod n

密碼分析者知道n、e1、e2、C1和C2,就能得到P。

因為e1和e2互質,故用Euclidean演算法能找到r和s,滿足:

r * e1 + s * e2 = 1

假設r為負數,需再用Euclidean演算法計算C1^(-1),則

( C1^(-1) )^(-r) * C2^s = P mod n

另外,還有其它幾種利用公共模數攻擊的方法。總之,如果知道給定模數
的一對e和d,一是有利於攻擊者分解模數,一是有利於攻擊者計算出其它
成對的e』和d』,而無需分解模數。解決辦法只有一個,那就是不要共享
模數n。

RSA的小指數攻擊。 有一種提高
RSA速度的建議是使公鑰e取較小的值,這樣會使加密變得易於實現,速度
有所提高。但這樣作是不安全的,對付辦法就是e和d都取較大的值。

RSA演算法是第一個能同時用於加密和數字簽名的演算法,也易於理解和操作。
RSA是被研究得最廣泛的公鑰演算法,從提出到現在已近二十年,經歷了各
種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。
RSA的安全性依賴於大數的因子分解,但並沒有從理論上證明破譯RSA的難
度與大數分解難度等價。即RSA的重大缺陷是無法從理論上把握它的保密性
能如何,而且密碼學界多數人士傾向於因子分解不是NPC問題。

RSA的缺點主要有:
A)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次
一密。B)分組長度太大,為保證安全性,n 至少也要 600 bits
以上,使運算代價很高,尤其是速度較慢,較對稱密碼演算法慢幾個數量級;
且隨著大數分解技術的發展,這個長度還在增加,不利於數據格式的標准化。
目前,SET(Secure Electronic Transaction)協議中要求CA採用2048比特長
的密鑰,其他實體使用1024比特的密鑰。
參考資料:http://superpch.josun.com.cn/bbs/PrintPost.asp?ThreadID=465
CRC加解密演算法
http://www.bouncycastle.org/

6. java給漢字進行RSA加密

//加密操作
Mtext="ninhao!123您好!";
Mtext=java.net.URLEncoder.encode(Mtext,"GBK");
byte ptext[]=Mtext.getBytes("GBK");//將字元串轉換成byte類型數組,實質是各個字元的二進制形式
BigInteger m=new BigInteger(ptext);//二進制串轉換為一個大整數
...
...
//解密操作
...
...
byte[]mt=m.toByteArray();//m為密文的BigInteger類型
String str=(new String(mt,"GBK"));
str=java.net.URLDecoder.decode(str,"GBK");

7. 高分求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/

8. 如何實現用javascript實現rsa加解密

  1. 服務端生成公鑰與私鑰,保存。

  2. 客戶端在請求到登錄頁面後,隨機生成一字元串。

  3. 後此隨機字元串作為密鑰加密密碼,再用從服務端獲取到的公鑰加密生成的隨機字元串

  4. 將此兩段密文傳入服務端,服務端用私鑰解出隨機字元串,再用此私鑰解出加密的密文。這其中有一個關鍵是解決服務端的公鑰,傳入客戶端,客戶端用此公鑰加密字元串後,後又能在服務端用私鑰解出。

步驟:

  1. 服務端的RSAJava實現:

    /**
    *
    */
    packagecom.sunsoft.struts.util;

    importjava.io.ByteArrayOutputStream;
    importjava.io.FileInputStream;
    importjava.io.FileOutputStream;
    importjava.io.ObjectInputStream;
    importjava.io.ObjectOutputStream;
    importjava.math.BigInteger;
    importjava.security.KeyFactory;
    importjava.security.KeyPair;
    importjava.security.KeyPairGenerator;
    importjava.security.NoSuchAlgorithmException;
    importjava.security.PrivateKey;
    importjava.security.PublicKey;
    importjava.security.SecureRandom;
    importjava.security.interfaces.RSAPrivateKey;
    importjava.security.interfaces.RSAPublicKey;
    importjava.security.spec.InvalidKeySpecException;
    importjava.security.spec.RSAPrivateKeySpec;
    importjava.security.spec.RSAPublicKeySpec;

    importjavax.crypto.Cipher;/**
    *RSA工具類。提供加密,解密,生成密鑰對等方法。
    *需要到
    下載bcprov-jdk14-123.jar。
    *
    */
    publicclassRSAUtil{
    /**
    **生成密鑰對*
    *
    *@returnKeyPair*
    *@throwsEncryptException
    */
    ()throwsException{
    try{
    KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance("RSA",
    neworg.bouncycastle.jce.provider.BouncyCastleProvider());
    finalintKEY_SIZE=1024;//沒什麼好說的了,這個值關繫到塊加密的大小,可以更改,但是不要太大,否則效率會低
    keyPairGen.initialize(KEY_SIZE,newSecureRandom());
    KeyPairkeyPair=keyPairGen.generateKeyPair();
    saveKeyPair(keyPair);
    returnkeyPair;
    }catch(Exceptione){
    thrownewException(e.getMessage());
    }
    }

    publicstaticKeyPairgetKeyPair()throwsException{
    FileInputStreamfis=newFileInputStream("C:/RSAKey.txt");
    ObjectInputStreamoos=newObjectInputStream(fis);
    KeyPairkp=(KeyPair)oos.readObject();
    oos.close();
    fis.close();
    returnkp;
    }

    publicstaticvoidsaveKeyPair(KeyPairkp)throwsException{

    FileOutputStreamfos=newFileOutputStream("C:/RSAKey.txt");
    ObjectOutputStreamoos=newObjectOutputStream(fos);
    //生成密鑰
    oos.writeObject(kp);
    oos.close();
    fos.close();
    }

    /**
    **生成公鑰*
    *
    *@parammolus*
    *@parampublicExponent*
    *@returnRSAPublicKey*
    *@throwsException
    */
    (byte[]molus,
    byte[]publicExponent)throwsException{
    KeyFactorykeyFac=null;
    try{
    keyFac=KeyFactory.getInstance("RSA",
    neworg.bouncycastle.jce.provider.BouncyCastleProvider());
    }catch(NoSuchAlgorithmExceptionex){
    thrownewException(ex.getMessage());
    }

    RSAPublicKeySpecpubKeySpec=newRSAPublicKeySpec(newBigInteger(
    molus),newBigInteger(publicExponent));
    try{
    return(RSAPublicKey)keyFac.generatePublic(pubKeySpec);
    }catch(InvalidKeySpecExceptionex){
    thrownewException(ex.getMessage());
    }
    }

    /**
    **生成私鑰*
    *
    *@parammolus*
    *@paramprivateExponent*
    *@returnRSAPrivateKey*
    *@throwsException
    */
    (byte[]molus,
    byte[]privateExponent)throwsException{
    KeyFactorykeyFac=null;
    try{
    keyFac=KeyFactory.getInstance("RSA",
    neworg.bouncycastle.jce.provider.BouncyCastleProvider());
    }catch(NoSuchAlgorithmExceptionex){
    thrownewException(ex.getMessage());
    }

    RSAPrivateKeySpecpriKeySpec=newRSAPrivateKeySpec(newBigInteger(
    molus),newBigInteger(privateExponent));
    try{
    return(RSAPrivateKey)keyFac.generatePrivate(priKeySpec);
    }catch(InvalidKeySpecExceptionex){
    thrownewException(ex.getMessage());
    }
    }

    /**
    **加密*
    *
    *@paramkey
    *加密的密鑰*
    *@paramdata
    *待加密的明文數據*
    *@return加密後的數據*
    *@throwsException
    */
    publicstaticbyte[]encrypt(PublicKeypk,byte[]data)throwsException{
    try{
    Ciphercipher=Cipher.getInstance("RSA",
    neworg.bouncycastle.jce.provider.BouncyCastleProvider());
    cipher.init(Cipher.ENCRYPT_MODE,pk);
    intblockSize=cipher.getBlockSize();//獲得加密塊大小,如:加密前數據為128個byte,而key_size=1024
    //加密塊大小為127
    //byte,加密後為128個byte;因此共有2個加密塊,第一個127
    //byte第二個為1個byte
    intoutputSize=cipher.getOutputSize(data.length);//獲得加密塊加密後塊大小
    intleavedSize=data.length%blockSize;
    intblocksSize=leavedSize!=0?data.length/blockSize+1
    :data.length/blockSize;
    byte[]raw=newbyte[outputSize*blocksSize];
    inti=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++;
    }
    returnraw;
    }catch(Exceptione){
    thrownewException(e.getMessage());
    }
    }

    /**
    **解密*
    *
    *@paramkey
    *解密的密鑰*
    *@paramraw
    *已經加密的數據*
    *@return解密後的明文*
    *@throwsException
    */
    publicstaticbyte[]decrypt(PrivateKeypk,byte[]raw)throwsException{
    try{
    Ciphercipher=Cipher.getInstance("RSA",
    neworg.bouncycastle.jce.provider.BouncyCastleProvider());
    cipher.init(cipher.DECRYPT_MODE,pk);
    intblockSize=cipher.getBlockSize();
    ByteArrayOutputStreambout=newByteArrayOutputStream(64);
    intj=0;

    while(raw.length-j*blockSize>0){
    bout.write(cipher.doFinal(raw,j*blockSize,blockSize));
    j++;
    }
    returnbout.toByteArray();
    }catch(Exceptione){
    thrownewException(e.getMessage());
    }
    }

    /**
    ***
    *
    *@paramargs*
    *@throwsException
    */
    publicstaticvoidmain(String[]args)throwsException{
    RSAPublicKeyrsap=(RSAPublicKey)RSAUtil.generateKeyPair().getPublic();
    Stringtest="helloworld";
    byte[]en_test=encrypt(getKeyPair().getPublic(),test.getBytes());
    byte[]de_test=decrypt(getKeyPair().getPrivate(),en_test);
    System.out.println(newString(de_test));
    }
    }
  2. 測試頁面IndexAction.java:

    /*
    *GeneratedbyMyEclipseStruts
    *Templatepath:templates/java/JavaClass.vtl
    */
    packagecom.sunsoft.struts.action;

    importjava.security.interfaces.RSAPrivateKey;
    importjava.security.interfaces.RSAPublicKey;

    importjavax.servlet.http.HttpServletRequest;
    importjavax.servlet.http.HttpServletResponse;

    importorg.apache.struts.action.Action;
    importorg.apache.struts.action.ActionForm;
    importorg.apache.struts.action.ActionForward;
    importorg.apache.struts.action.ActionMapping;

    importcom.sunsoft.struts.util.RSAUtil;

    /**
    *MyEclipseStruts
    *Creationdate:06-28-2008
    *
    *XDocletdefinition:
    *@struts.actionvalidate="true"
    */
    {
    /*
    *GeneratedMethods
    */

    /**
    *Methodexecute
    *@parammapping
    *@paramform
    *@paramrequest
    *@paramresponse
    *@returnActionForward
    */
    publicActionForwardexecute(ActionMappingmapping,ActionFormform,
    HttpServletRequestrequest,HttpServletResponseresponse)throwsException{

    RSAPublicKeyrsap=(RSAPublicKey)RSAUtil.getKeyPair().getPublic();
    Stringmole=rsap.getMolus().toString(16);
    Stringempoent=rsap.getPublicExponent().toString(16);
    System.out.println("mole");
    System.out.println(mole);
    System.out.println("empoent");
    System.out.println(empoent);
    request.setAttribute("m",mole);
    request.setAttribute("e",empoent);
    returnmapping.findForward("login");
    }
    }

    通過此action進入登錄頁面,並傳入公鑰的Molus 與PublicExponent的hex編碼形式。

9. 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多位元組的其他空字元。

10. java的MD5withRSA演算法可以看到解密的內容么

您好,
<一>. MD5加密演算法:
? ? ? ?消息摘要演算法第五版(Message Digest Algorithm),是一種單向加密演算法,只能加密、無法解密。然而MD5加密演算法已經被中國山東大學王小雲教授成功破譯,但是在安全性要求不高的場景下,MD5加密演算法仍然具有應用價值。
?1. 創建md5對象:?
<pre name="code" class="java">MessageDigest md5 = MessageDigest.getInstance("md5");
?2. ?進行加密操作:歲宏?
byte[] cipherData = md5.digest(plainText.getBytes());

?3. ?將其中的每個位元組轉成十六進制字元串:byte類型的數據最高位是符號位,通過和0xff進行與操作,轉換為int類型的正整數。?
String toHexStr = Integer.toHexString(cipher & 0xff);

?4. 如果該正數小於16(長度為1個字元),前面拼接0佔位:確保最後生成的是32位字元串。?
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);

?5.?加密轉換之後的字元串為:?
?6. 完整的MD5演算法應用如下所示:?
/**
* 功能簡述: 測試MD5單向加密.
* @throws Exception
*/
@Test
public void test01() throws Exception {
String plainText = "Hello , world !"乎派冊;
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] cipherData = md5.digest(plainText.getBytes());
StringBuilder builder = new StringBuilder();
for(byte cipher : cipherData) {
String toHexStr = Integer.toHexString(cipher & 0xff);
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);
}
System.out.println(builder.toString());
//
}

??
<二>. 使用BASE64進行加密/解密:
? ? ? ? 使用BASE64演算法通常用作對二進制數據進行加密,加密之後的數據不易被肉眼識別。嚴格來說,經過BASE64加密的數據其實沒有安全性可言,因為它的加密解密演算法都是公開的,典型的防菜鳥不防程序羨逗猿的呀。?經過標準的BASE64演算法加密後的數據,?通常包含/、+、=等特殊符號,不適合作為url參數傳遞,幸運的是Apache的Commons Codec模塊提供了對BASE64的進一步封裝。? (參見最後一部分的說明)
?1.?使用BASE64加密:?
BASE64Encoder encoder = new BASE64Encoder();
String cipherText = encoder.encode(plainText.getBytes());

? 2.?使用BASE64解密:?
BASE64Decoder decoder = new BASE64Decoder();
plainText = new String(decoder.decodeBuffer(cipherText));

? 3. 完整代碼示例:?
/**
* 功能簡述: 使用BASE64進行雙向加密/解密.
* @throws Exception
*/
@Test
public void test02() throws Exception {
BASE64Encoder encoder = new BASE64Encoder();
BASE64Decoder decoder = new BASE64Decoder();
String plainText = "Hello , world !";
String cipherText = encoder.encode(plainText.getBytes());
System.out.println("cipherText : " + cipherText);
//cipherText : SGVsbG8gLCB3b3JsZCAh
System.out.println("plainText : " +
new String(decoder.decodeBuffer(cipherText)));
//plainText : Hello , world !
}

??
<三>. 使用DES對稱加密/解密:
? ? ? ? ?數據加密標准演算法(Data Encryption Standard),和BASE64最明顯的區別就是有一個工作密鑰,該密鑰既用於加密、也用於解密,並且要求密鑰是一個長度至少大於8位的字元串。使用DES加密、解密的核心是確保工作密鑰的安全性。
?1.?根據key生成密鑰:?
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
SecretKey secretKey = keyFactory.generateSecret(keySpec);

? 2.?加密操作:?
Cipher cipher = Cipher.getInstance("des");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());
byte[] cipherData = cipher.doFinal(plainText.getBytes());

? 3.?為了便於觀察生成的加密數據,使用BASE64再次加密:?
String cipherText = new BASE64Encoder().encode(cipherData);

? ? ?生成密文如下:PtRYi3sp7TOR69UrKEIicA==?
? 4.?解密操作:?
cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());
byte[] plainData = cipher.doFinal(cipherData);
String plainText = new String(plainData);

? 5. 完整的代碼demo:?
/**
* 功能簡述: 使用DES對稱加密/解密.
* @throws Exception
*/
@Test
public void test03() throws Exception {
String plainText = "Hello , world !";
String key = "12345678"; //要求key至少長度為8個字元

SecureRandom random = new SecureRandom();
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
SecretKey secretKey = keyFactory.generateSecret(keySpec);

Cipher cipher = Cipher.getInstance("des");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
byte[] cipherData = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));
//PtRYi3sp7TOR69UrKEIicA==

cipher.init(Cipher.DECRYPT_MODE, secretKey, random);
byte[] plainData = cipher.doFinal(cipherData);
System.out.println("plainText : " + new String(plainData));
//Hello , world !
}

??
<四>. 使用RSA非對稱加密/解密:
? ? ? ? RSA演算法是非對稱加密演算法的典型代表,既能加密、又能解密。和對稱加密演算法比如DES的明顯區別在於用於加密、解密的密鑰是不同的。使用RSA演算法,只要密鑰足夠長(一般要求1024bit),加密的信息是不能被破解的。用戶通過https協議訪問伺服器時,就是使用非對稱加密演算法進行數據的加密、解密操作的。
? ? ? ?伺服器發送數據給客戶端時使用私鑰(private key)進行加密,並且使用加密之後的數據和私鑰生成數字簽名(digital signature)並發送給客戶端。客戶端接收到伺服器發送的數據會使用公鑰(public key)對數據來進行解密,並且根據加密數據和公鑰驗證數字簽名的有效性,防止加密數據在傳輸過程中被第三方進行了修改。
? ? ? ?客戶端發送數據給伺服器時使用公鑰進行加密,伺服器接收到加密數據之後使用私鑰進行解密。
?1.?創建密鑰對KeyPair:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");
keyPairGenerator.initialize(1024); //密鑰長度推薦為1024位.
KeyPair keyPair = keyPairGenerator.generateKeyPair();

? 2.?獲取公鑰/私鑰:
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

? 3.?伺服器數據使用私鑰加密:
Cipher cipher = Cipher.getInstance("rsa");
cipher.init(Cipher.ENCRYPT_MODE, privateKey, new SecureRandom());
byte[] cipherData = cipher.doFinal(plainText.getBytes());

? 4.?用戶使用公鑰解密:
cipher.init(Cipher.DECRYPT_MODE, publicKey, new SecureRandom());
byte[] plainData = cipher.doFinal(cipherData);

? 5.?伺服器根據私鑰和加密數據生成數字簽名:
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(cipherData);
byte[] signData = signature.sign();

? 6.?用戶根據公鑰、加密數據驗證數據是否被修改過:
signature.initVerify(publicKey);
signature.update(cipherData);
boolean status = signature.verify(signData);

? 7. RSA演算法代碼demo:<img src="http://www.cxyclub.cn/Upload/Images/2014081321/99A5FC9C0C628374.gif" alt="尷尬" title="尷尬" border="0">
/**
* 功能簡述: 使用RSA非對稱加密/解密.
* @throws Exception
*/
@Test
public void test04() throws Exception {
String plainText = "Hello , world !";

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();

PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

Cipher cipher = Cipher.getInstance("rsa");
SecureRandom random = new SecureRandom();

cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
byte[] cipherData = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));
//gDsJxZM98U2GzHUtUTyZ/Ir/
///ONFOD0fnJoGtIk+T/+3yybVL8M+RI+HzbE/jdYa/+
//yQ+vHwHqXhuzZ/N8iNg=

cipher.init(Cipher.DECRYPT_MODE, publicKey, random);
byte[] plainData = cipher.doFinal(cipherData);
System.out.println("plainText : " + new String(plainData));
//Hello , world !

Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(cipherData);
byte[] signData = signature.sign();
System.out.println("signature : " + new BASE64Encoder().encode(signData));
//+
//co64p6Sq3kVt84wnRsQw5mucZnY+/+vKKXZ3pbJMNT/4
///t9ewo+KYCWKOgvu5QQ=

signature.initVerify(publicKey);
signature.update(cipherData);
boolean status = signature.verify(signData);
System.out.println("status : " + status);
//true
}

閱讀全文

與rsa加密演算法java相關的資料

熱點內容
acmc用什麼編譯器 瀏覽:230
golangweb編譯部署 瀏覽:923
怎樣踩東西解壓 瀏覽:969
單片機核心板外接鍵盤 瀏覽:396
怎樣打開自己的微信文件夾 瀏覽:424
單片機紅外測距原理 瀏覽:268
phpxdebug擴展 瀏覽:757
建築樓層凈高演算法 瀏覽:1000
怎麼關閉智聯app求職狀態 瀏覽:418
pdf的文件夾怎麼列印 瀏覽:752
延拓演算法初值 瀏覽:786
首次適應演算法都不滿足的話怎麼辦 瀏覽:19
php56加密 瀏覽:556
金立手機app怎麼設置浮窗 瀏覽:496
程序員沒有社會地位 瀏覽:963
榮耀app怎麼解鎖 瀏覽:594
php程序員學歷 瀏覽:636
c語言編譯可以嗎 瀏覽:201
脂硯齋重評石頭記pdf 瀏覽:756
三星冰箱壓縮機哪裡產 瀏覽:429