創建用於測試的斷鍊證書
在我們的軟體中,我們從客戶那裡收到二進制 DER 格式的證書。它們預先用於在伺服器和客戶端之間執行某些身份檢查。為確保證書有效且可信,我們會驗證證書鏈。使用我們可用的 API,這很容易實現。
但主要問題是:我們如何創建某些證書實際上具有損壞的信任鍊或任何應該驗證的完整性問題。生成有效的似乎很容易,但是為了測試我們的驗證系統,我們需要無效的。
我想了解對我的有效證書進行哪些更改以引入前面提到的錯誤。它可以在二進制級別上輕鬆完成還是有工具可以做到?我試圖尋找解釋,但我發現的只是關於如何修復已經損壞的證書。我希望要麼我需要更改公鑰的某些字節,要麼更改頒發者的詳細資訊。
我個人編寫了一個通用的 ASN.1 解碼器/編碼器工具。它被稱為DDer。它將 DER 編碼的對象轉換為結構化的文本表示(帶括號,有點讓人想起 Lisp)。有趣的是,它附帶了一個配套工具 MDer,它可以執行反向轉換。因此,您可以使用文本編輯器編輯證書內容,MDer 將計算出編碼細節。
現在剩下的一個棘手的部分是簽名。證書是經過簽名的,更改證書中的任何位都會使簽名無效,因此這需要簽名工具。我碰巧編寫了自己的加密庫(在 C# 中,尚未發布),它可以在任意 DER 編碼的對像上應用簽名,甚至修補
SignatureAlgorithm
證書的待簽名結構中的內部。不過,在緊急情況下,可以藉助該
dc
實用程序“手動”計算 RSA 簽名,該實用程序是類 Unix 系統中的標準問題。該計算器可以使用十六進制輸入和輸出,處理任意長的整數,並使用集成|
運算符計算模冪。工作流程將是:
- 在 DDer 的文本表示中創建待簽名結構,並使用 MDer 將其轉換為 DER。在涉足證書時,您通常從現有證書開始,因此對它進行 DDer 化。
- 使用
sha256sum
(Linux 上的另一個標準命令行工具)計算待簽名的 SHA-256 雜湊。- 將散列值組裝到適合RSA的適當填充結構中。您想在文本編輯器中將其設為十六進制。確保你所有的十六進制都是大寫的,沒有多餘的空格,因為這是需要的
dc
。- 在私鑰文件上使用 DDer 來獲取關鍵元素,特別是模數(第一個大整數)和私有指數(結構中的第三個大整數)(第二個大整數是公共指數,通常不是那麼大)。
- 用於
dc
計算模冪。您切換dc
到十六進制輸入和輸出16 i 10 o
(讀作“將輸入基數設置為 16,然後將輸出基數設置為 10”;“10”以十六進制解釋,因為您剛剛將輸入基數切換為 16!)。然後複製並粘貼操作數(填充散列、私有指數、模數,按此順序),併計算模冪 (|
)。您用於p
列印結果,它將是十六進制的。- 回到待簽名的 DDer 文本表示,編寫包裝結構,它是
SEQUENCE
包含待簽名的 aAlgorithmIdentifier
,標識簽名算法的 aBIT STRING
,其內容是簽名值的 a。MDer 會期望BIT STRING
內容是十六進制的,就像你剛剛從 獲得的一樣dc
,所以這是一個複制和粘貼的問題(再次)。- 最後一個 MDer 生成最終證書,DER 編碼。
- 如果您需要 PEM 格式的新證書,請使用 with
openssl
或直接使用該base64
工具(同樣是 Linux 中常用的命令行工具)進行轉換,然後手動添加-----BEGIN CERTIFICATE-----
and-----END CERTIFICATE-----
行(如果您故意製作了錯誤編碼的證書,這可能是必要的,openssl
不接受轉換)。如果您可以按順序完成所有這些步驟,那麼您就足夠了解 RSA 和 ASN.1 來編寫自己的工具來應用簽名。如果使用 C#,您可以重用來自 DDer 的 ASN.1 庫,以及
ZInt
用於一些非常基本且敷衍的 RSA 實現的大整數類 ( )(在生產中使用不夠安全,但可用於製作測試案例)。