RSA加密算法原理及RES签名算法简介(转载)
第一部分:RSA算法原理與加密解密
一、RSA加密過程簡(jiǎn)述
A和B進(jìn)行加密通信時(shí),B首先要生成一對(duì)密鑰。一個(gè)是公鑰,給A,B自己持有私鑰。A使用B的公鑰加密要加密發(fā)送的內(nèi)容,然后B在通過自己的私鑰解密內(nèi)容。
?
二、RSA加密算法基礎(chǔ)
整個(gè)RSA加密算法的安全性基于大數(shù)不能分解質(zhì)因數(shù)。
三、數(shù)學(xué)原理
(一)??互質(zhì)關(guān)系:兩個(gè)數(shù)a和b沒有除1外的其他公約數(shù),則a與b互質(zhì)
1.????????任意兩個(gè)質(zhì)數(shù)構(gòu)成互質(zhì)關(guān)系
2.????????兩個(gè)數(shù)中,如果大數(shù)為質(zhì)數(shù),則兩數(shù)必定互質(zhì)
3.????????1和任意整數(shù)互質(zhì)
4.????????當(dāng)p>1時(shí),p與p-1互質(zhì)(相鄰兩數(shù)互質(zhì))
5.????????當(dāng)p=2n+1(n>0且n為整數(shù))時(shí),p與p+2互質(zhì)(相連的兩個(gè)奇數(shù)互質(zhì))
(二)??求歐拉函數(shù):
定義:與正整數(shù)n互質(zhì)且小于正整數(shù)n的正整數(shù)的個(gè)數(shù)。通常使用ψ(n)表示。
?
求取與正整數(shù)n互質(zhì)的正整數(shù)的個(gè)數(shù)ψ(n),且ψ(n)滿足ψ(n)∈(2,n)
1.????????如果n=1,則ψ(n)=1
2.????????如果n是質(zhì)數(shù),則ψ(n)=n-1
3.????????如果n是質(zhì)數(shù)p的次方,則:ψ(p^k)=p^k-p^(k-1) = p^k*(1-1/p)
4.????????若p1和p2互質(zhì),n=p1*p2,則ψ(n)= ψ(p1*p2)= ψ(p1) ψ(p2)
5.????????任意一個(gè)大于1的正整數(shù)都可以寫成一系列質(zhì)數(shù)的積
6.????????根據(jù)定理5,推導(dǎo)歐拉定理:
因?yàn)?/p>
???????? n = (p1^k1)* (p2^k2)*……(pr^kr)?? (p1~pr都是質(zhì)數(shù))
所以
???????? ψ(n)= ψ((p1^k1)) ψ(p2^k2) ……ψ(pr^kr)?? 定理4
???????? ψ(n)= (p1^k1)*(1-1/p1) * (p2^k2)(1-1/p2)……(pr^kr)*(1-1/pr)?? 定理3
???????? ψ(n)= (p1^k1)* (p2^k2)*……(pr^kr) * (1-1/p1) (1-1/p2)…… (1-1/pr)
???????? ψ(n)=n (1-1/p1) (1-1/p2)…… (1-1/pr)??
(三)??歐拉定理:
正整數(shù)a與n互質(zhì),則下式恒成立
a^ψ(n) ≡1(mod n)
即:
???????? a的ψ(n)次冪除以n,余數(shù)恒為1
(四)??模反元素
如果兩個(gè)正整數(shù)a和n互質(zhì),則必定存在整數(shù)b使得a*b-1被n除余數(shù)為1
ab ≡1(mod n)
其中b被稱為a的模反元素
?
四、RSA算法詳解:假設(shè)A和B要通信
(一)??生成密鑰
1.????????公鑰
1)????????隨機(jī)生成兩個(gè)不相等的質(zhì)數(shù)p和q(質(zhì)數(shù)越大越安全)
2)????????計(jì)算n,n=p*q 則n的二進(jìn)制位數(shù)就是密鑰的長(zhǎng)度。
3)????????計(jì)算n的歐拉函數(shù)ψ(n)????????
因?yàn)?/p>
n=p*q
所以
ψ(n) =ψ(p)* ψ(q)??? 定理4
又p和q為質(zhì)數(shù)
所以
ψ(p)=p-1????定理2
ψ(q)=q-1????定理2
所以
?????????????????? ψ(n) = (p-1)(q-1)
4)????????獲取隨機(jī)正整數(shù)e,e滿足? e∈(1, ψ(n))且e與ψ(n)互質(zhì)(通常選擇65537)
將n和e封裝成公鑰
????????
2.????????私鑰
1)????????計(jì)算e對(duì)于ψ(n)的模反元素d
e*d=1(modψ(n));
設(shè)正整數(shù)k, e*d = kψ(n)+1;
?
則ed-kψ(n)=1
? d = (kψ(n)+1) / e;
對(duì)于不定方程ax+by=c,設(shè)gcd(a,b)=d,如果ax+by=c有解,則d|c----->也就是說如果ed-kψ(n)=1 有解,則gcd(d,-k)能夠整除1,而1顯然可以被任何整數(shù)整除,所以該二元一次方程必定有解(d,k)
?
?(歐幾里得定理和擴(kuò)展歐幾里得定理計(jì)算二元一次方程)
2)????????將n和d封裝成私鑰
?
?
五、RSA算法可靠性論證
從上文可以統(tǒng)計(jì)出整個(gè)算法涉及到的量有6個(gè),其中三個(gè)為由私鑰持有者生成,三個(gè)是私鑰持有者推導(dǎo)出來的
生成量:p,q,e
推導(dǎo)量:n, ψ(n),d
?
密鑰中只有公鑰被發(fā)布,所有人都可以獲取。而公鑰由n和e封裝起來,因此,如果要破解一份RSA加密過的密文,我們必須使用私鑰(私鑰由n和d封裝而成)
n可以從公鑰獲取。
?
(假設(shè)mc為明文,c為密文,則公鑰由n和e封裝則意味著求取密文的運(yùn)算中,n,e和mc是已知數(shù),只有c是未知數(shù);私鑰由n和d封裝,同上,解密密文的運(yùn)算中,n,d和c是已知的,只有mc是未知數(shù)。)
?
因此,破解私鑰的關(guān)鍵就是破解e對(duì)于ψ(n)的模反元素d。
???????? 其數(shù)學(xué)關(guān)系是:? e*d=1(modψ(n));
因此需需要先求出ψ(n),而求出ψ(n)需要知道ψ(p)和ψ(q)(因?yàn)棣?n)= ψ(p* ψ(q))
?
而p和q只能通過分解n的質(zhì)因數(shù)獲得。所以,整個(gè)RSA算法都基于n這個(gè)大數(shù)不能分解質(zhì)因數(shù)這個(gè)基礎(chǔ)上。
????????
因此,只要n夠大,私鑰就不會(huì)被破解
?
?
六、加解密過程:假設(shè)明文是m,c是密文
(一)??加密:使用公鑰(n,e)
先將其換算成asc碼或者unicode等其他數(shù)值。且m必須小于n
則加密算法是
???????? m^e=c(mod n)
推出
???????? m^e / n = k ……c這里c就是密文,k我們不關(guān)心
(二)??解密:使用私鑰(n,d)
1.????????簡(jiǎn)單的說解密就是通過下式求m。(一定可以求解出m)
c^d = m(mod n)
推出
c^d / n = k … … m??? m就是明文編碼,不關(guān)心k
?
查表得出明文
?
?
第二部分:RSA算法簽名與驗(yàn)簽
?
假設(shè)A要想B發(fā)送消息,A會(huì)先計(jì)算出消息的消息摘要,然后使用自己的私鑰加密這段摘要加密,最后將加密后的消息摘要和消息一起發(fā)送給B,被加密的消息摘要就是“簽名”。
B收到消息后,也會(huì)使用和A相同的方法提取消息摘要,然后使用A的公鑰解密A發(fā)送的來簽名,并與自己計(jì)算出來的消息摘要進(jìn)行比較。如果相同則說明消息是A發(fā)送給B的,同時(shí),A也無法否認(rèn)自己發(fā)送消息給B的事實(shí)。
其中,A用自己的私鑰給消息摘要加密成為“簽名”;B使用A的公鑰解密簽名文件的過程,就叫做“驗(yàn)簽”。
?
數(shù)字簽名的作用是保證數(shù)據(jù)完整性,機(jī)密性和發(fā)送方角色的不可抵賴性
?
下面是對(duì)簽名和驗(yàn)簽過程的簡(jiǎn)要描述:
?
l? 簽名過程:
1.????????A計(jì)算消息m的消息摘要,記為 h(m)
2.????????A使用私鑰(n,d)對(duì)h(m)加密,生成簽名s ,s滿足:
s=(h(m))^d mod n;
由于A是用自己的私鑰對(duì)消息摘要加密,所以只用使用s的公鑰才能解密該消息摘要,這樣A就不可否認(rèn)自己發(fā)送了該消息給B。
3.????????A發(fā)送消息和簽名(m,s)給B。
?
l? 驗(yàn)簽過程:
1.????????B計(jì)算消息m的消息摘要,記為h(m);
2.????????B使用A的公鑰(n,e)解密s,得到
H(m) = s^e mod n;
3.????????B比較H(m)與h(m),相同則證明
?
第三部分:總結(jié)
?
下面簡(jiǎn)單總結(jié)加密和解密的完整過程。
?
l ?簽名過程:
1.????????A提取消息m的消息摘要h(m),并使用自己的私鑰對(duì)摘要h(m)進(jìn)行加密,生成簽名s
2.????????A將簽名s和消息m一起,使用B的公鑰進(jìn)行加密,生成密文c,發(fā)送給B。
l ?驗(yàn)證過程:
1.????????B接收到密文c,使用自己的私鑰解密c得到明文m和數(shù)字簽名s
2.????????B使用A的公鑰解密數(shù)字簽名s解密得到H(m).
3.????????B使用相同的方法提取消息m的消息摘要h(m)
4.????????B比較兩個(gè)消息摘要。相同則驗(yàn)證成功;不同則驗(yàn)證失敗。
?
下面是借鑒一個(gè)網(wǎng)友的Demo,加上我自己注釋后,打包的一個(gè)Demo。
?
EnAndDe.java
?
package com.joe.main;import java.io.*; import java.math.BigInteger; import java.util.ArrayList;/*** <p>* Company: 建工學(xué)院* </p>* * @author 04信息(1)程晟* @modify Joe* @Description Demo說明:* 1、按照加密解密和簽名驗(yàn)簽的邏輯,編寫簡(jiǎn)單的demo,不涉及java中繼承的RSA相關(guān)類和Sigesture簽名類* 2、只能對(duì)數(shù)字和字母進(jìn)行加密, 不涉及編碼和解碼問題 。 3、不做數(shù)字簽名和驗(yàn)證了,涉及到提取信息摘要。*/ public class EnAndDe {private long p = 0;private long q = 0;private long n = 0;private long t = 0; // 歐拉函數(shù)private long e = 0; // 公匙private long d = 0; // 密匙private String mc; // 明文private long c = 0; // 密文private long word = 0; // 解密后明文// 判斷是一個(gè)數(shù) x 否為素?cái)?shù)素?cái)?shù)就是判斷在 (2,√x)范圍內(nèi)有沒有除1外的因數(shù),如果沒有則x數(shù)素?cái)?shù)public boolean isPrime(long t) {long k = 0;k = (long) Math.sqrt((double) t);for (int i = 2; i <= k; i++) {if ((t % i) == 0) {return false;}}return true;}// 隨機(jī)產(chǎn)生大素?cái)?shù)(1e6數(shù)量級(jí),注意,太大了要超出范圍)public void bigprimeRandom() {do {p = (long) (Math.random() * 1000000);} while (!this.isPrime(p));do {q = (long) (Math.random() * 1000000);} while (p == q || !this.isPrime(q));}// 輸入PQpublic void inputPQ() throws Exception {this.bigprimeRandom();System.out.println("自動(dòng)生成兩個(gè)大素?cái)?shù)p,q分別為:" + this.p + " " + this.q);this.n = (long) p * q;this.t = (long) (p - 1) * (q - 1);System.out.println("這兩個(gè)素?cái)?shù)的乘積為p*q:" + this.n);System.out.println("所得的t=(p-1)(q-1):" + this.t);}// 求最大公約數(shù)public long gcd(long a, long b) {long gcd;if (b == 0)gcd = a;elsegcd = gcd(b, a % b);return gcd;}// 生成公匙public void getPublic_key() throws Exception {do {this.e = (long) (Math.random() * 100000);// e滿足 e∈(1, ψ(n))且e與ψ(n)最大公約數(shù)為1,即 e與t互質(zhì)} while ((this.e >= this.t) || (this.gcd(this.t, this.e) != 1));System.out.println("生成的公鑰為:" + "(" + this.n + "," + this.e + ")");}// 生成私鑰 e*d=1(modψ(n))==> d = (kψ(n)+1) / epublic void getPrivate_key() {long value = 1; // value 是e和d的乘積outer: for (long k = 1;; k++) {value = k * this.t + 1;if ((value % this.e == 0)) {this.d = value / this.e;break outer;}}System.out.println("產(chǎn)生的一個(gè)私鑰為:" + "(" + this.n + "," + this.d + ")");}// 輸入明文public void getText() throws Exception {System.out.println("請(qǐng)輸入明文:");BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));mc = stdin.readLine();}// 解密密文public void pascolum() throws Exception {this.getText();System.out.println("輸入明文為: " + this.mc);// 加密ArrayList cestr = new ArrayList();for (int i = 0; i < mc.length(); i++) {this.c = this.colum((long) mc.charAt(i), this.n, this.e);cestr.add(c);}System.out.println("加密后所得的密文為:" + cestr);// 解密StringBuffer destr = new StringBuffer();for (int j = 0; j < cestr.size(); j++) {this.word = this.colum(Long.parseLong(cestr.get(j).toString()),this.n, this.d);destr.append((char) word);}System.out.println("解密后所得的明文為:" + destr);}// 加密、解密計(jì)算public long colum(long mc, long n, long key) {BigInteger bigy = new BigInteger(String.valueOf(mc));BigInteger bign = new BigInteger(String.valueOf(n));BigInteger bigkey = new BigInteger(String.valueOf(key));return Long.parseLong(bigy.modPow(bigkey, bign).toString());// 備注1}public static void main(String[] args) {try {EnAndDe t = new EnAndDe();t.inputPQ();t.getPublic_key();t.getPrivate_key();t.pascolum();} catch (Exception e) {e.printStackTrace();}}}備注1:modPow(a,b)是java類BigInteger中的一個(gè)方法,返回結(jié)果是:調(diào)用該方法的對(duì)象的a次冪,模b的結(jié)果
轉(zhuǎn)載于:https://www.cnblogs.com/pang-blog/p/4092143.html
總結(jié)
以上是生活随笔為你收集整理的RSA加密算法原理及RES签名算法简介(转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 静态页中调用动态数据的三种办法
- 下一篇: 仔细学习CSS(二)