Algorithm-Design

TEA 的填充物

  • February 22, 2021

終於弄清楚瞭如何在 C++ 中實現微型加密算法,我想知道如何填充密鑰和明文。

我知道有多種方法可以做到這一點,但是有沒有一種“預設”的方法可以做到這一點,還是有人做出選擇?

問題的片段“如何填充 密鑰 ”看起來很像使用某種填充機制將密碼轉換為加密密鑰。

這樣做將是一個眾所周知的、嚴重的、經常犯和經常被利用的錯誤。密碼的標準安全假設是密鑰是隨機選擇的,並且填充密碼不是隨機的。如果知道一小部分明文(如開頭的 8 個字節),那麼如果密碼是任何給定的值,則測試變得非常容易(以高可信度):成本是每個測試密碼的一個塊密碼(使用password 使密碼看起來是隨機的,但稍微提高了安全性:每次測試的成本僅增加一個雜湊值)。這是密碼破解的理想理由,基本上是在嘗試合理的密碼。許多工具使用 CPU 或 GPU 來做到這一點,有時速度遠遠超過 $ 10^9 $ 每 GPU 每秒。有它的業務,甚至是機架安裝單元中基於 FPGA 的設備;也許對於資金充足的組織,特定的矽。我強調我認可這些產品,也沒有破解密碼的做法。

將密碼轉換為適合分組密碼的密鑰是專門為密碼設計的密鑰派生函式(不是散列函式)的工作。此類功能需要可參數化的工作量,從而允許增加測試密碼是否正確所需的時間,即使測試密鑰是否正確仍然很容易。這可以大大提高對密碼破解的抵抗力(一個因素 $ 2^{30} $ 往往是現實的)。

PBKDF2(正式定義在RFC2898中)是常用的良好此類功能之一,它基於迭代散列。最先進的一個是Scrypt,它使用順序記憶體硬函式;它具有強大的安全原理,並在其內部循環中使用最佳原語之一(伯恩斯坦的 Salsa20);然而,這種質量使得它在許多無法有效實現 Salsa20 的實際案例中變得不方便,例如,當將軟體附加組件限制在某些解釋器上並通過有效實現訪問有限數量的加密原語時。

控制 RAM 使用量(對於 Scrypt)和迭代次數(對於所有基於密碼的密鑰派生函式)的參數應該被調高,增加從密碼計算密鑰的成本,限制在實用性。

PBKDF2 和 Scrypt 都有輸入。在加密的上下文中,鹽是一些公共數據,盡可能不被重用。Salt需要可用於解密,例如作為密文的前導碼。Salt 之所以有幫助是因為密碼會被重用(作為簡化由同一使用者重複使用,而不同的使用者會意外重複使用),並且沒有鹽會導致重複使用相同的密鑰,從而使密碼猜測的預計算成為可能,並促進一些攻擊。

如果可能的話,salt 可以是真正隨機的(256 位就足夠了),但真正的隨機很難收集,並且會增加明文的大小。為了減少成本,salt 可能是一些隱含已知的公共數據(設備序列號、使用者 ID、名稱、電子郵件..)或無論如何都需要傳輸(文件名/日期/大小..)。計數器需要較少的空間,但可以重置(意外或故意),並且很難讓多個使用者或電腦使用同一個計數器。時鐘時間 + 本地 MAC 地址的串聯通常不是唯一的,即使在超過時鐘粒度的時刻(時鐘可能由於調整、夏令時或故意而跳回;MAC 地址有時會被硬體製造商意外弄錯,以及通常使用可能會改變它的 API 讀取)。

一種很好的方法是從上面盡可能多地連接可以安全地公開的內容,並將其用作鹽,直接或在散列後使用,以減少鹽的大小/成本。


至於數據的填充機制:您需要一種,使用任何確定性標準,它們在功能上是等效的。無論您選擇哪種,請注意解密後填充不正確時會發生什麼情況,如果密文被破壞(意外或故意)可能會發生這種情況:檢查填充可能導致緩衝區溢出,並且顯示填充不正確可能會洩漏明文資訊。最簡單的方法是不填充數據:如果使用CFBOFBCTR ,則不需要任何數據填充。

引用自:https://crypto.stackexchange.com/questions/2839