RSA密鑰長度、明文長度和密文長度

轉自:https://blog.csdn.net/lvxiangan/article/details/45487943,部分語言和排版略做調整。

本文不涉及RSA加密原理,如想了解RSA加密原理請參考:RSA非對稱加密算法詳解

建議在閱讀本文前先讀RSA非對稱加密算法詳解。

本文介紹RSA加解密中必須考慮到的密鑰長度、明文長度和密文長度問題。提到密鑰,我們不得不提到RSA的三個重要大數:公鑰指數e、私鑰指數d和模值n。這三個大數是我們使用RSA時需要直接接觸的,理解了本文的基礎概念,即使未接觸過RSA的開發人員也能應對自如的使用RSA相關函數庫,無需深入瞭解e、d、n是如何生成的,只需要知道我該如何用、要注意什麼。

一、密鑰長度

1、密鑰是指誰?

首先我們說的“密鑰”是指誰?由於RSA密鑰是(公鑰+模值)、(私鑰+模值)分組分發的,單獨給對方一個公鑰或私鑰是沒有任何用處,所以我們說的“密鑰”其實是它們兩者中的其中一組。但我們說的“密鑰長度”一般只是指模值的位長度。目前主流可選值:1024、2048、3072、4096...

2、模值主流長度是多少?

目前主流密鑰長度至少都是1024bits以上,低於1024bit的密鑰已經不建議使用(安全問題)。那麼上限在哪裏?沒有上限,多大都可以使用。所以,主流的模值是1024位,實際運算結果可能會略小於1024bits,注意,這個值不是絕對的,跟素數的生成算法有關係,只是告訴素數生成器“幫我生成一個接近1024位的素數而已”,然後生成器“好,給您一個,這個差不多1024位”。

素數生成器這麼厲害?說生成1024位就會出個1024位的大整數?真實的情況是素數生成器也只是在1024bits對應的整數附近進行“摸索”而已,大家其實都不容易,又要快又要準確又要隨機性,那麼素數生成器也只能應付一下,找到1024位的算是好運,沒找到1024位,1023位也照樣送出來:)。

3、公鑰指數如何確定?

公鑰指數是隨意選的,但目前行業上公鑰指數普遍選的都是65537(0x10001,5bits),該值是除了1、3、5、17、257之外的最小素數,爲什麼不選的大一點?當然可以,只是考慮到既要滿足相對安全、又想運算的快一點(加密時),PKCS#1的一個建議值而已。

有意的把公鑰指數選的小一點,但是對應私鑰指數肯定很大,意圖也很明確,大家都要用公鑰加密,所以大家時間很寶貴,需要快一點,您一個人私鑰解密,時間長一點就多擔待,少數服從多數的典型應用。

4、私鑰指數如何確定?

公鑰指數隨意選,那麼私鑰就不能再隨意選了,只能根據算法公式(e*d mod k=1,k=(p-1)(q-1))進行運算出來。那麼私鑰指數會是多少位?根據ed關係,私鑰d=(x*k+1)/e(x爲任意整數),所以單看這個公式,私鑰指數似乎也不是唯一結果,可能大於也可能小於1024bits的,但我們習慣上也是指某個小於1024bits的大整數。

包括前文的公鑰指數,在實際運算和存儲時爲方便一般都是按照標準位長進行使用,前面不足部分補0填充,所以,使用保存和轉換這些密鑰需要注意統一緩衝區的長度。

二、明文長度

網上有說明文長度小於等於密鑰長度(Bytes)-11,這說法本身不太準確,會給人感覺RSA 1024只能加密117字節長度明文。實際上,RSA算法本身要求加密內容也就是明文長度m必須0<m<n,也就是說內容這個大整數不能超過n,否則就出錯。那麼如果m=0是什麼結果?普遍RSA加密器會直接返回全0結果。如果m>n,運算就會出錯?!那怎麼辦?且聽下文分解。

所以,RSA實際可加密的明文長度最大也是1024bits,但問題就來了:

如果小於這個長度怎麼辦?就需要進行padding,因爲如果沒有padding,用戶無法確分解密後內容的真實長度,字符串之類的內容問題還不大,以0作爲結束符,但對二進制數據就很難理解,因爲不確定後面的0是內容還是內容結束符。

只要用到padding,那麼就要佔用實際的明文長度,於是纔有117字節的說法。我們一般使用的padding標準有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建議的padding就佔用了11個字節。

如果大於這個長度怎麼辦?很多算法的padding往往是在後邊的,但PKCS的padding則是在前面的,此爲有意設計,有意的把第一個字節置0以確保m的值小於n。

這樣,128字節(1024bits)-減去11字節正好是117字節,但對於RSA加密來講,padding也是參與加密的,所以,依然按照1024bits去理解,但實際的明文只有117字節了。

關於PKCS#1 padding規範可參考:RFC2313 chapter 8.1,我們在把明文送給RSA加密器前,要確認這個值是不是大於n,也就是如果接近n位長,那麼需要先padding再分段加密。除非我們是“定長定量自己可控可理解”的加密不需要padding。

三、密文長度

密文長度就是給定符合條件的明文加密出來的結果位長,這個可以確定,加密後的密文位長跟密鑰的位長度是相同的,因爲加密公式:

C=(M^e) mod n

所以,密文C最大值就是n-1,所以不可能超過模值n的位數。儘管可能小於模值n的位數,但從傳輸和存儲角度,仍然是按照標準位長來進行的,所以,即使我們加密一字節的明文,運算出來的結果也要按照標準位長來使用(當然了,除非我們能再採取措施區分真實的位長,一般不在考慮)。

至於明文分片多次加密,自然密文長度成倍增長,但已不屬於一次加密的問題,不能放到一起考慮。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章