RSA:拋開算法不談,我們如何將字元串轉換為整數,反之亦然?
假設我要加密文件
plain.txt
。第一步實際上是將該文件的內容(假設它僅包含字元串“Hello”)轉換為 int。我看到這樣的python程式碼:from Crypto.Util.number import bytes_to_long with open('plain.txt', 'rb') as f: flag = f.read() m = bytes_to_long(flag)
但是,我不太明白髮生了什麼。此外,當密文已被解碼回明文但仍為數字形式時,我看不到
long_to_bytes
或任何將數字轉換為字元串的東西。我懂了import binascii binascii.unhexlify('{:x}'.format(m))
這看起來與其他程式碼完全不同,但它仍然有效。有人可以向我解釋這些過程,以便我了解編碼算法的輸入和輸出,而不僅僅是算法本身。
基本上有兩個步驟:
- 將文本編碼為字節 - 這通常需要字元編碼,例如 UTF-8 或拉丁編碼;
- 將字節編碼為整數 - 這是PKCS#1 中指定的 RSA 中加密操作的一部分,並使用稱為 OS2IP 的函式執行。
在您的情況下,文本顯然已經編碼為字節;文件畢竟由字節組成,並且您將文件作為二進製文件打開(rb 標誌中的 b )。
OS2IP 表示八位字節字元串到整數原語。八位字節串只不過是一個字節數組。如果字節已經是正確的形式,那麼這只是將字節解釋為數字的問題,因為電腦總是將所有內容都作為二進制處理。
但是,在基於 PKCS#1 的 RSA OS2IP 中不直接使用:首先應用安全相關的填充。這將是 PKCS#1 v1.5 定義的填充或 OAEP 填充。添加填充意味著在應用消息之前添加了不小的成本;明文的數量遠小於 RSA 模數。
這就是為什麼文件通常不直接使用 RSA 加密的原因之一。另一個主要原因是 RSA 加密,尤其是解密操作與例如基於 AES 的加密相比效率非常低。相反,我們使用諸如 PGP 之類的協議來執行混合加密。安全操作模式下的 RSA 有一定的成本,並且每次操作有一個最大值,所以一般對稱密鑰是使用 RSA 加密或派生的;然後使用此對稱密鑰對數據進行加密。AES 等對稱密碼直接對二進制數據進行操作,因此除了處理 IV 和填充之外,數據可以直接加密而無需轉換。
編輯
在分析已知遊戲和攻擊後,對 RSA 算法進行了修改,被認為適用於長消息。 如何加強 RSA-OAEP 的安全性,Boldyreva 等人。
原始答案
您的問題解決了分組密碼的概念。在核心中,您有一個算法,它對定義大小的字節塊進行操作;根據定義的操作模式,對數據塊進行預處理或後處理。最簡單的模式是原子 ECB,“電子密碼本”模式,沒有“知識”,即您將輸入流“plain.txt”拆分為定義大小的數據包,按順序加密它們並將輸出連接到輸出流中,例如’加密的.bin’。在您閱讀二進製文件時,您已經預料到從文本到八位字節(=字節)的轉換。在 CBC 等其他操作模式中,來自先前塊的 CTR 輸入或輸出是塊加密的附加輸入。
這些模式涵蓋了基於字節輸入流的碎片和記憶體的結構方面,您以“plain.txt”開頭。
現在來處理塊:通常將填充算法應用於輸入塊,該算法通過散列函式添加鹽和/或混合輸入字節,“OAEP”是常見的候選者。教科書 RSA 省略了填充。
下一步是從填充輸出塊過渡到數值算法,即您“擱置”的算法。如前所述,這被定義為 PKCS#1,也是從數字空間到字節塊的映射。
關於維度:您從 RSA 密鑰長度和相關的模數開始,這限制了等效數據塊的大小。填充通常會再次減小使用者數據的最大大小。對這個可用塊大小的評估是分片的基本輸入。
最後,解密需要知道原始流的長度。這也必須編碼。例如,您在輸入流前面加上它的長度。
注意:將分組密碼模式應用於 RSA 在政治上是不正確的,有些人會建議您限製文本文件的大小。聽他們的,如果你想,他們會解決你的問題。:) 無論如何,流將吸引分組密碼概念。