X.509 序列號的不可預測性
關於 X.509 證書序列號,RFC 5280說:
序列號必須是 CA 分配給每個證書的正整數。對於給定 CA 頒發的每個證書,它必須是唯一的(即,頒發者名稱和序列號標識唯一的證書)。CA 必須強制 serialNumber 為非負整數。
沒有提到序列號生成的安全問題。有哪些好的做法?可預測的(例如順序或基於證書生成日期)序列號是否存在任何安全問題?
非隨機序列號本身並不意味著簽名方案存在安全問題,但正如@Jack 指出的那樣,它可以用來利用攻擊。一般來說,簽名算法首先使用給定的散列函式對輸入消息進行散列;如果消息或散列過程完全由攻擊者控制,那麼散列函式的抗碰撞性就成為一個重要問題。另一方面,由於簽名者插入了一些隨機性(例如,隨機序列號,由證書的頒發 CA 添加),簽名應該能夠抵抗單純的衝突攻擊,並且最終可以抵抗原像(和MD5,儘管有其所有缺點,但似乎仍然對原像具有最佳抗性)。
這種隨機性應該以“適當”的方式插入,這取決於雜湊函式的內部結構。Halevi 和 Krawczyk 指定了一種適用於所有雜湊函式的通用方法,並將其稱為RMX。它產生了網際網路草案和 NIST 特別出版物SP-800-106。值得注意的點是:
- RMX 旨在應用於任何二進制消息,但它需要生成一些隨機值,以便與消息一起傳輸。
- 由於散列過程被修改,簽名者和驗證者必須在消息處理開始時就知道 RMX。
- RMX 包含如何從 DSA/ECDSA 簽名的前半部分提取隨機值的描述(“ $ r $ “值,它不依賴於簽名的消息)。這是為了節省頻寬並與現有的數據格式兼容(沒有額外的“隨機值”的空間),但它使簽名更加複雜,因為” $ r $ " 然後必須在對輸入消息進行散列之前生成值——在散列被外部化的系統中,在另一個模組中,而不是在持有簽名私鑰的模組中,這可能很麻煩。
- 這是一個尚未在任何值得注意的標準中找到方法的建議。
使用隨機序列號是“窮人的隨機散列”,它具有與現有 X.509 證書驗證器完全兼容的優良特性(散列過程和證書格式不會以任何方式改變)並且許多 CA 已經實現了它,儘管不是為了防止碰撞攻擊。在證書中,序列號“足夠早”出現在結構中,在它和公鑰之間有一些大的固定元素(即,主題和頒發者名稱,有效期……),因此它就足夠了,現有的 MD基於散列函式(MD5、SHA-1…),以防止利用碰撞攻擊。還有,夠長隨機序列號以壓倒性的機率確保唯一性,而無需在數據庫中查找任何內容。為獲得適當的互操作性,請使用小於等於的正序列號 $ 2^{159} $ (這確保了 ASN.1 DER 中指定的值編碼將適合 20 個字節)。
與衝突和簽名完全無關,但與安全相關,可預測的序列號會洩露業務資訊。正如 Peter Gutmann 在他的X.509 樣式指南(一個古老但有趣且並非完全過時的文本)中所述:
通過使用序列號,CA 最終揭示了它實際簽署了多少證書(以每週一份證書為代價,比賽可以準確地找出每週發行了多少證書)