關於密碼中的RSA演算法和ecc(橢圓曲線)演算法加密過程是怎樣的?
作者:Kalafinaian
連結:https://www.zhihu.com/question/26662683/answer/325511510
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
Oblivious 何処へ行くの
贊同 1159 條評論
分享
收藏感謝
收起
使用者標識
密碼學 話題的優秀回答者
47 人贊同了該回答
RSA請移步至這個答案,包含對題主問題的解答:
密碼學裡講的橢圓曲線(EC),是解析式形如 的曲線,其中x的定義域通常在整數集合上【注1】,不是解析幾何裡講的橢圓。
如果視曲線上的點P:(x,y)為一個元素,則整數a對P的乘法定義為:
這裡的“+”是一個比較特殊的計算,對於已知不同兩點P,Q, P+Q是這麼算的:
如果P=Q, P+Q的演算法稍有不同:
具體過程用代數式表達如下:(需考慮P=Q的情況)
以上演算法和圖片引自 Understanding Cryptography by C.Paar,
P = (x1,y1), Q=(x2,y2), +和-在演算法中為普通四則運算,除法在中進行。
連結
根據這種加法運算,可以定義一個新的"離散對數問題":
已知G為EC上的一個點,EC引數和點K1已知,求滿足的整數k2。
EC所生成的群,通常用來代替基於“離散對數問題”的加密方案或者數字簽名中用到的群。比如EC-ElGamal,是把原來ElGama中使用的
概要翻譯:
曲線引數A,B已知,點G已知,公鑰為K1,
加密時選取一個隨機整數r, 生成密文
解密時,用私鑰k2參與計算,解出明文
安全性證明我就不寫了,請參考原始論文。
【注1】密碼學中一般考慮橢圓曲線定義在Finite Field上的情況,包括Integer Field。例如,定義一個EC為,且, 其中p為素數。
但實際上,橢圓曲線本身可以定義在實數空間甚至複數空間上。
贊同 472 條評論
分享
收藏感謝
收起
12 人贊同了該回答
文章來自我的部落格,稍作修改。文章閱讀需要高中數學知識以及對計算複雜度有基本概念。不要求瞭解群論相關內容。
序言
不管是RSA還是ECC或者其它,公鑰加密演算法都是依賴於某個正向計算很簡單(多項式時間複雜度),而逆向計算很難(指數級時間複雜度)的數學問題。
現代公鑰加密系統中,離散對數加密和橢圓曲線加密形式比較相似,在這裡一併介紹。
離散對數問題
我們在中學裡學的對數問題是指,
給定正實數a和a^x,求x。也就是計算x=log(a^x)。
這是實數域上的對數問題,不是什麼難算的東西,隨便按一下計算器結果就出來了。
而離散對數問題是指這樣的問題:
給定素數p和正整數g,知道g^x mod p的值,求x
對於符合特定條件的p和g,當x非常大時,使用傳統計算機求x需要花費的時間會長到無法承受。
Diffie–Hellman金鑰交換
Diffie–Hellman金鑰交換(以下簡稱DH)是用於雙方在可能被竊聽環境下安全交換金鑰的一種方法。
演算法的安全性是由上面提到的離散對數難題保證。
具體演算法流程如下:
- 小紅和小明約定p和g的值
- 小紅生成私鑰x,計算g^x mod p作為公鑰公佈出去
- 小明生成私鑰y,計算g^y mod p作為公鑰公佈出去
- 小紅得知g^y mod p後,計算
- 小明得到g^x mod p後,計算
- 雙方都得到了相同的金鑰s,交換完畢
流程中,x和y始終由兩人自行保管的,第三方竊聽得到的只有p、g、g^x mod p和g^y mod p這幾個值。
上面說過,離散對數是很難算的,所以第三方不能由這些資訊計算出x或y,也就沒辦法計算出金鑰s了。
橢圓曲線
中學的時候我們學過圓錐曲線,比如橢圓、雙曲線和拋物線。因為描述這些曲線的方程都是二次方程,圓錐曲線又被稱為二次曲線。而橢圓曲線是則是由三次方程描述的一些曲線。更準確地說,橢圓曲線是由下面的方程描述的曲線:
需要注意的是,橢圓曲線之所以叫“橢圓曲線”,是因為其曲線方程跟利用微積分計算橢圓周長的公式相似。實際上它的影象跟橢圓完全不搭邊。
下圖是橢圓曲線y^2=x^3-x+1的影象
橢圓曲線有這樣的兩個性質:
- 關於X軸對稱
- 畫一條直線跟橢圓曲線相交,它們最多有三個交點
橢圓曲線上的運算
由於橢圓曲線加密進行的運算實際上都是在橢圓曲線上進行的,所以接下來需要定義一些橢圓曲線上的運算。
必須注意的是,這裡把這些運算稱為“加法”和“乘法”僅僅是方便描述,他們跟平時認知的加法和乘法完全是兩碼事,完全可以給他們取其它名字(比如”乘法“和”冪運算“等)。
- 首先定義座標系中距離X軸無窮遠點為橢圓曲線上的一個特殊點,稱為0點(零點)。
那麼此時上述第二條性質可以加強為:過曲線上任意兩點(可重合)的直線必定與曲線相交於第三點。 - 然後定義橢圓曲線上點的加法。設橢圓曲線上有兩點,A和B點,那麼作過這兩點的直線與該曲線相交於第三點(C點),然後關於X軸對稱得到D點,則D為這兩個點的和,記作D=A+B。很明顯,D點也在該曲線上。所以橢圓曲線上兩點之和也是曲線上的點。
特別地,如果兩點重合,則作橢圓曲線在A點處的切線,與曲線相交於第二點(B點),然後關於X軸對稱得到C點,則C點為A點與自身的和,記作C=A+A
那麼關於這個加法,我們可以得到以下結論:
- A+B=B+A
交換律。直線是沒有方向的,因此從A出發作過B點的直線與從B點出發作過A點的直線是相同的。 - (A+B)+C=A+(B+C)
結合律。這個結論並不直觀,需要較為複雜的證明,此處不做介紹,有興趣的可以看看這裡。
- 對於曲線上任意一點A,都存在曲線上另一點B,使得A+B=0
因為曲線關於X軸對稱,所以曲線上總有另一點B使得過A、B的直線垂直於X軸,也就是該直線與曲線交於0點,所以A+B=0。
- A+0=A
因為0點是距離X軸無窮遠的點,所以過A點與0點的直線是垂直於X軸的,它與曲線相交於另一點B點,那麼B點關於X軸對稱的點就是A點,即A點和0點之和就是A點自身。
然後在加法的基礎上,定義橢圓曲線上點的乘法。
設P是橢圓曲線上的一個點,那麼正整數k乘以點P的結果由下面的式子定義,注意式子中的加法是上面提到的橢圓曲線上點的加法:
1P=P 2P=P+P
3P=2P+P
...
kP=(k-1)P+P
從程式實現的角度來考慮,假設有這麼一個函式:
Point add(Point A, Point B) {...}
函式引數是兩個橢圓曲線上的點,返回值是過兩個點的直線與橢圓曲線相交的第三個點關於X軸對稱的點。
那麼按照如下方式呼叫函式:
Point result = P;
for (int i = 0; i < k - 1; i++)
result = add(P, result);
sendTo((result, P), others);
也就是通過不斷地迭代相加,就可以得到kP。
這個乘法滿足以下性質:
對於任意正整數k和j,有
這個性質在橢圓曲線金鑰交換中會利用到。
橢圓曲線上的離散對數問題
定義了基本的加法和乘法運算後,我們可以由此得到橢圓曲線加密依賴的數學難題。
k為正整數,P是橢圓曲線上的點(稱為基點),已知kP和P,計算k
上面我們提到過橢圓曲線上點的加法滿足結合律,那麼,我們可以用快速冪的方法來計算kP,時間複雜度為 ,因此計算kP並不困難。這個問題的難度在於,對於第三方而言,只知道kP和P的值,想要反過來求出k的值,目前沒有比列舉k的值好太多的演算法。如果k特別大(比如在區間[2^255, 2^256]上),那麼需要列舉的次數甚至已經遠遠超出天文數字的概念了。
如果我們改一種記法,把橢圓曲線上點的加法記作乘法,原來的乘法就變成了冪運算,那麼上述難題的形式跟離散對數問題應該是一致的。即:
k為正整數,P是橢圓曲線上的點,已知P^k和P,計算k=log(P^k)。
儘管兩者形式一致,但是他們並不等價。實際上這個問題比大整數質因子分解(RSA)和離散對數(DH)難題都要難得多,以致於同樣的安全強度下,橢圓曲線加密的金鑰比RSA和DH的要短不少,這是橢圓曲線加密的一大優勢。
有限域上的橢圓曲線
但是密碼學中,並不能使用上面介紹的實數域上的橢圓曲線。因為
1. 實數域上的橢圓曲線是連續的,有無限個點,密碼學要求有限點。
2. 實數域上的橢圓曲線的運算有誤差,不精確。密碼學要求精確。
所以我們需要引入有限域上的橢圓曲線。
所謂有限域上的橢圓曲線,簡單來說就是滿足下面式子要求的曲線(x, y, a, b都是小於素數p的非負整數):
對比一下原先的橢圓曲線的方程:
可以看到這個只是對原式進行了簡單的取模處理而已。
原本連續的曲線變成了離散的點,基本已經面目全非了,但是依然可以看到它是關於某條水平直線(y=97/2)對稱的。
而且上面定義的橢圓曲線的加法仍然可用(當然乘法也可以)(圖片來自參考文獻)。
注意:密碼學中有限域上的橢圓曲線一般有兩種,一種是定義在以素數p為模的有限域GF(p),也就是上面介紹的;另一種則是定義在特徵為2的有限域GF(2^m)上,篇幅所限,這裡就不介紹了。
基於橢圓曲線的DH金鑰交換(ECDH)
ECDH跟DH的流程基本是一致的。
- 小紅和小明約定使用某條橢圓曲線(包括曲線引數,有限域引數以及基點P等)
- 小紅生成私鑰x,計算xP作為公鑰公佈出去
- 小明生成私鑰y,計算yP作為公鑰公佈出去
- 小紅得知yP後,計算
- 小明得到xP後,計算
- 雙方都得到了相同的金鑰s(因為s是一個點,實際上會取s的橫座標值作為金鑰),交換完畢。
由於計算橢圓曲線上的離散對數是很難的,所以第三方沒辦法在只知道xP和yP的情況下計算出x或y的值。
實際應用中,我們並不需要關心橢圓曲線的眾多引數如何選取(要選對引數對於普通使用者來說並不現實),只要從密碼學家們精心挑選的一堆曲線中選擇一個就行了。一般來說曲線Curve25519,prime256v1是比較常用的,比特幣選擇secp256k1則是因為它效率較高,並且其引數是可預測的,降低了包含後門的可能性。
參考文獻
文中除引用圖外,其它作圖均使用GeoGebra完成。