非對稱加密算法RSA中的公鑰和私鑰

*本文只討論一個問題,在非對稱加密算法RSA中,什麼是公鑰什麼是私鑰html

非對稱加密算法

非對稱加密算法有不少,例如RSA、Elgamal、揹包算法、Rabin、D-H、ECC(橢圓曲線加密算法)。java

在在這些算法中,RSA最爲經常使用,所以,在沒有特殊說明的狀況下,常說的公鑰、私鑰都指的是RAS的公鑰、私鑰。算法

這裏也是以RSA算法爲例,來討論非對稱加密中的公鑰和私鑰安全

RSA加密算法

要想了解公鑰和私鑰的區別,就要從它們的產生開始。
這裏我默認讀者已經瞭解了RSA算法。若是還不瞭解,請先去看這兩篇文章。
RSA算法原理(一)
RSA算法原理(二)
特別是 RSA算法原理(二)必定要仔細看一遍,否則下面的內容你將看不懂。bash

RSA加密算法中的公鑰和私鑰

看過上面兩篇文章的人應該已經知道了,在RSA加密算法中有6個很是關鍵數字,他們是算法的核心。
這6個數字分別是函數

  • 大質數p
  • 另外一個大質數q
  • p和q的乘積n
  • n的歐拉函數φ(n)  注:φ(n) = (p-1)(q-1)
  • 一個隨機整數e,1< e < φ(n),且e與φ(n) 互質
  • e對於φ(n)的模反元素d  注:所謂"模反元素"就是指有一個整數d,可使得ed被φ(n)除的餘數爲1。

其中(n,e)在一塊兒組成了公鑰,(n,d)在一塊兒組成了私鑰。工具

如今讓咱們來回答最開始提出是問題,什麼是公鑰,什麼是私鑰。
答:公鑰爲(n,e) 私鑰爲(n,d)學習

文章到此結束,謝謝你們的閱讀!編碼

番外1

其實咱們仔細想一想就會發現,(n,e) 和 (n,d) 根本沒什麼區別。爲何一個叫公鑰一個叫私鑰呢?反過來行不行?加密

答案是能夠的,根據算法原理咱們知道,只有 (n,e) 是算不出 (n,d) 的,反過來只有 (n,d) 也是算不出 (n,e) 的。因此反過來也是安全的。

那咱們就不經思考了,既然反過來也能夠,那公鑰私鑰還有什麼區別,爲何一個叫公鑰,一個叫私鑰呢。

我想了好久,最終想到了一個合理的解釋,被公開的祕鑰就叫公鑰,沒有被公開的祕鑰就叫私鑰。網上多數的回答也證明了個人想法。

原來 公鑰和私鑰並非根據 (n,e) 和 (n,d) 區分的,而是根據使用上的不一樣來區分的

番外2

讓咱們再思考一個問題。
在工做中,咱們常常會用到各類生成祕鑰的工具。這些工具通常會爲咱們生成兩個文件。一個公鑰文件,假設叫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 (公開祕鑰加密標準),旗下包含十幾個子標準,每一個子標準負責一個領域。)

這樣作有兩個好處

  1. 公鑰和私鑰的重要性和地位再也不同樣,私鑰的重要性和地位遠高於公鑰,這有利於私鑰的持有者。
  2. 擁有了私鑰,就至關於擁有了公鑰,使用起來特別方便,就算公鑰弄丟了,還能夠經過私鑰生成出來。

(從上文咱們瞭解到,理論和實現仍是有區別的,理論跟偏向原理,而實現更偏向使用,因此實際中的私鑰會比理論中的私鑰多幾個參數。)


如今咱們能夠回答最開始提出的問題了,在非對稱加密算法RSA中,什麼是公鑰什麼是私鑰。

  1. 公鑰首先是一種祕鑰,它包含(n,e),能夠被公開,不能推導出私鑰
  2. 私鑰首先也是一種祕鑰,他有兩種語法格式,pkcs#8標準語法格式的和pkcs#1標準語法格式,其中pkcs#1規定,私鑰包含(n,e,d,p,q),不能夠被公開,能夠推導出公鑰。

在實際應用中,絕大多數對RSA的實現,都遵循pkcs的標準,即私鑰能推出公鑰,但公鑰不能推出私鑰

總結

經過上面的文章咱們至少要知道如下幾點

  • 公鑰和私鑰不同
  • 私鑰能夠推導出公鑰,但公鑰沒法推導出私鑰(私鑰包含公鑰)
  • 理論和實現是有出入的,因此只學習理論是沒法爲咱們解惑的,必須聯繫實際進行思考才能解答咱們的疑問。

番外3

祕鑰格式

生成的祕鑰通常會經過PEM編碼成文原本存儲。具體以下:

  • PKCS1語法格式私鑰:傳統格式,PHP、.NET通常使用此格式
  • PKCS8語法格式私鑰:java通常使用此格式
  • PKCS1格式和PKCS8格式的私鑰,導出的公鑰內容是一摸同樣的

公鑰是不分 pkcs1 格式和 pkcs8格式的,由於公鑰就只有一種語法格式。

RSA密鑰語法

RSA公鑰在PKCS#1標準中定義的語法

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}
(n,e)
複製代碼

RSA私鑰在PKCS#1標準中定義的語法

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)
複製代碼

RSA私鑰在PKCS#8標準中定義的語法

pkcs#8 全稱 Private-Key Information Syntax Standard 私鑰信息語法標準,是專門爲私鑰而設計的規範,因此是不存在PKCS#8格式的公鑰這一說

PrivateKeyInfo ::= SEQUENCE {  
version	Version,	//版本 
privateKeyAlgorithm	PrivateKeyAlgorithmIdentifier, 	//算法標示符 
privateKey	PrivateKey,  //私鑰
attributes		[0]  IMPLICIT Attributes OPTIONAL 
} 
複製代碼
相關文章
相關標籤/搜索