C# 使用AE獲取feature的屬性及欄位操作
阿新 • • 發佈:2021-01-15
文章目錄
一、生成公鑰和私鑰
1、隨機生成兩個隨機素數P,Q
2、將P、Q兩個素數相乘得到一個數N,即N=P*Q(需要公開)
3、將P、Q分別減1再相乘得到一個數T,即T=(P-1)*(Q-1)
4、選擇一個數E,E滿足和T互質且E小於T
5、根據DE mod T = 1計算出金鑰D
6、通過以上步驟可以得到N,E,D這3個數字,其中(N、E)作為公鑰,(N、D)作為私鑰(公鑰和私鑰可以互換)
二、加密和解密
接受方將生成的公鑰(N,E)對外發布
1、用公鑰加密
傳送方用接受到的公鑰(N,E)對密文M加密
加密:ME mod N = C
明文:C
2、用私鑰解密
接受方用持有私鑰(N,D)對明文C解密
明文:C
解密:CD mod N = M
密文:M
三、java實現
public class RSA {
private int N; // 和公鑰E一起分發出去
private int E; // E是公鑰,隨機選取(必須和T互質)
private int D; // D是金鑰(D和E可以互換)
public RSA() {
createKey();
}
// 產生金鑰
private void createKey () {
// 產生兩個隨機的素數
int p=61,q=53;
// 計算N和T
N = p*q;
int t = (p-1)*(q-1);
// 選擇E(和T互質就行)
E = 17;
// 計算D
int[] r = new int[2];
Gcd.extendGcd(E, t, r); // 呼叫擴充歐幾里得演算法計算D
D = r[0];
// 調整d(d為正數)
while(D < 0) D +=t;
}
/**
* 利用公鑰對密文m加密
* @param m 必須是整數,且m必須小於N
* @return c=pow(m,E)%N
*/
public int encrypt(int m) { // 注意,這裡很容易溢位(雖然此演算法已經極度簡化了)
BigInteger bm = BigInteger.valueOf(m);
return bm.pow(E).mod(BigInteger.valueOf(N)).intValue();
}
/**
* 利用金鑰對明文c解密
* @param c
* @return m1=pow(c, D)%N
*/
public int decrypt(int c) { // 同樣考慮溢位情況
BigInteger bc = BigInteger.valueOf(c);
return bc.pow(D).mod(BigInteger.valueOf(N)).intValue();
}
public int getPublicKey() {
return E;
}
public void setPublicKey(int E) {
this.E = E;
}
public int getN() {
return N;
}
public void setN(int N) {
this.N = N;
}
public static void main(String[] args) {
RSA rsa = new RSA();
System.out.println("公鑰:E="+rsa.getPublicKey()+",N="+rsa.getN()); // 列印公鑰
int m = 65; // 明文
System.out.println("密文:"+m);
int c = rsa.encrypt(m); // 對明文m加密,得到密文c
System.out.println("明文:"+c);
int m1 = rsa.decrypt(c); // 對密文c解密,得到明文m1
System.out.println("解密出來的密文:"+m1);
}
}
參考
阮一峰的部落格RSA演算法原理
周穎的《程式設計師的數學思維修煉》