*
本文只討論一個問題,在非對稱加密算法RSA中,什麼是公鑰什麼是私鑰html
非對稱加密算法有不少,例如RSA、Elgamal、揹包算法、Rabin、D-H、ECC(橢圓曲線加密算法)。java
在在這些算法中,RSA最爲經常使用,所以,在沒有特殊說明的狀況下,常說的公鑰、私鑰都指的是RAS的公鑰、私鑰。算法
這裏也是以RSA算法爲例,來討論非對稱加密中的公鑰和私鑰 。安全
要想了解公鑰和私鑰的區別,就要從它們的產生開始。
這裏我默認讀者已經瞭解了RSA算法。若是還不瞭解,請先去看這兩篇文章。
RSA算法原理(一)
RSA算法原理(二)
特別是 RSA算法原理(二)必定要仔細看一遍,否則下面的內容你將看不懂。bash
看過上面兩篇文章的人應該已經知道了,在RSA加密算法中有6個很是關鍵數字,他們是算法的核心。
這6個數字分別是函數
其中(n,e)在一塊兒組成了公鑰,(n,d)在一塊兒組成了私鑰。工具
如今讓咱們來回答最開始提出是問題,什麼是公鑰,什麼是私鑰。
答:公鑰爲(n,e) 私鑰爲(n,d)學習
文章到此結束,謝謝你們的閱讀!編碼
其實咱們仔細想一想就會發現,(n,e) 和 (n,d) 根本沒什麼區別。爲何一個叫公鑰一個叫私鑰呢?反過來行不行?加密
答案是能夠的,根據算法原理咱們知道,只有 (n,e) 是算不出 (n,d) 的,反過來只有 (n,d) 也是算不出 (n,e) 的。因此反過來也是安全的。
那咱們就不經思考了,既然反過來也能夠,那公鑰私鑰還有什麼區別,爲何一個叫公鑰,一個叫私鑰呢。
我想了好久,最終想到了一個合理的解釋,被公開的祕鑰就叫公鑰,沒有被公開的祕鑰就叫私鑰。網上多數的回答也證明了個人想法。
原來 公鑰和私鑰並非根據 (n,e) 和 (n,d) 區分的,而是根據使用上的不一樣來區分的
讓咱們再思考一個問題。
在工做中,咱們常常會用到各類生成祕鑰的工具。這些工具通常會爲咱們生成兩個文件。一個公鑰文件,假設叫public.key。一個私鑰文件,假設叫private.key。
根據上文的結論,咱們是否能將private.key當作公鑰公開,將public.key當作私鑰,保留呢?
答案是 不能夠!!!你們千萬別去這麼作!
爲何,按照上文的結論 「被公開的祕鑰就叫公鑰,未被公開的祕鑰就叫私鑰」,不該該是能夠嗎?爲何不能夠?
除非,上面的結論是錯的!!!
是的,上面的結論是錯的,公鑰和私鑰並非根據使用上的不一樣來區分的,也不是根據(n,e) 和 (n,d) 來區分的。
那公鑰和私鑰是經過什麼來區分的,到底有沒有區別。
彆着急,讓咱們先來看一個有趣的現象
在一些祕鑰生成工具中,有一個功能叫作 根據私鑰推導出公鑰 ,這個功能能夠根據私鑰文件,推導出公鑰文件來。 好比螞蟻金服的祕鑰生成工具
學習了RSA算法原理的人確定想說,這不可能,無論私鑰是(n,d)仍是(n,e) ,只有 (n,e) 是算不出 (n,d) 的,只有 (n,d) 也是算不出 (n,e) 的。
難道是阿里的人太nb了,能夠算出來嗎?
固然不是!要真是這樣,這種加密算法就不安全了。
那這個功能是怎麼實現的了!
答案是私鑰中包含了公鑰信息!!!
讓咱們作個實驗,隨便用什麼祕鑰生成工具,生成一對祕鑰,而後以文本的方式打開,你會發現,私鑰的內容老是比公鑰的多! 再仔細觀察你會發現 公鑰中的部份內容在私鑰中也存在!
這裏最好用文本對比工具,這樣看的比較清楚,我知道大家懶得去動手,因此我幫大家作好了!
爲何會這樣, 公鑰難道不是(n,e) 私鑰難道不是(n,d) 嗎!
按照RSA算法的定義,公鑰確實是(n,e) 私鑰也確實的(n,d)。
可是,實際應用中,人們發現,這樣作的話,公鑰和私鑰的重要性和地位就同樣了,但其實咱們最關心的是私鑰,私鑰纔是最重要的。
因而
在pkcs標準中,pkcs#1規定,私鑰包含(n,e,d,p,q),公鑰包含(n,e)
在pkcs標準中,pkcs#1規定,私鑰包含(n,e,d,p,q),公鑰包含(n,e)
在pkcs標準中,pkcs#1規定,私鑰包含(n,e,d,p,q),公鑰包含(n,e)
重要的話說三遍
(pkcs全稱Public-Key Cryptography Standards (公開祕鑰加密標準),旗下包含十幾個子標準,每一個子標準負責一個領域。)
這樣作有兩個好處
(從上文咱們瞭解到,理論和實現仍是有區別的,理論跟偏向原理,而實現更偏向使用,因此實際中的私鑰會比理論中的私鑰多幾個參數。)
如今咱們能夠回答最開始提出的問題了,在非對稱加密算法RSA中,什麼是公鑰什麼是私鑰。
在實際應用中,絕大多數對RSA的實現,都遵循pkcs的標準,即私鑰能推出公鑰,但公鑰不能推出私鑰
經過上面的文章咱們至少要知道如下幾點
生成的祕鑰通常會經過PEM編碼成文原本存儲。具體以下:
公鑰是不分 pkcs1 格式和 pkcs8格式的,由於公鑰就只有一種語法格式。
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
(n,e)
複製代碼
RSAPrivateKey ::= SEQUENCE {
version Version, //版本
modulus INTEGER, // RSA合數模 n
publicExponent INTEGER, //RSA公開冪 e
privateExponent INTEGER, //RSA私有冪 d
prime1 INTEGER, //n的素數因子p
prime2 INTEGER, //n的素數因子q
exponent1 INTEGER, //值 d mod (p-1)
exponent2 INTEGER, //值 d mod (q-1)
coefficient INTEGER, //CRT係數 (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
(n,e,d,p,q)
複製代碼
pkcs#8 全稱 Private-Key Information Syntax Standard 私鑰信息語法標準,是專門爲私鑰而設計的規範,因此是不存在PKCS#8格式的公鑰這一說
PrivateKeyInfo ::= SEQUENCE {
version Version, //版本
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, //算法標示符
privateKey PrivateKey, //私鑰
attributes [0] IMPLICIT Attributes OPTIONAL
}
複製代碼