如何從Windows注冊表中提取證書
Windows 注冊表中包含有二進制塊(Blob),有些二進制塊用于存儲證書,如下所示:

以下的注冊表位置都存儲證書:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates HKEY_CURRENT_USER\SOFTWARE\Microsoft\SystemCertificates
證書通過 DER格式進行編碼,總是以 0x30 為開始。但可以發現,在注冊表中找到的二進制塊并非以 0x30 開頭,這是因為證書前綴存儲了一些元數據。搜索 0x30 即可找到證書的位置:

并非所有以 0x30 開頭的字節序列都是有效的證書。從 0x30 8 開始搜索,提取該字節序列直到二進制塊的結尾找到了該證書。


該方法并不精確,通過查看幾個二進制塊可以發現:每個證書都以 4 字節為前綴,這些字節對證書的長度進行編碼(小端序),然后此長度字段以不變的 8 字節為前綴:20 00 00 00 01 00 00 00。

看起來像是 TLV的格式,每個證書的類型都是 20 00 00 00 01 00 00 00。工具 format-bytes.py是解析二進制數據的工具,可用于解析 TLV 記錄,如下所示:

中 <表示小端序,Q表示 unsigned long long(8 字節),I表示 unsigned int(4字節)。t:0意味著類型字段是第一個字段。l:1意味著長度字段是第二個字段。
可以看出,該二進制塊包含 11 個 TLV 記錄,最后一個長度為 1239,并且包含證書類型 0x100000020L。
進一步的研究表明,類型字段實際上由兩個字段組成:屬性標識符字段與保留字段,均為四個字節。屬性標識符的可能值可以在 Windows 開發中心和 wincrypt.h 頭文件中找到。
這意味著二進制塊內的 TLV 記錄可以使用 format-bytes.py -f “tlv=f:進行解析:

例如,記錄 5 的類型為 0x0b 代表是 CERT_FRIENDLY_NAME_PROP_ID:

如上圖所示,包含 UTF16 編碼的發行者名稱。如下所示,證書本身位于記錄 11 內(類型為 0x20):

要提取證書請使用 -d執行二進制 dump 并寫入本地文件:

結論
二進制數據塊中經常出現 TLV 記錄,如果想要識別二進制塊中的數據,請多比較幾個示例可能就會發現定義的模式。證書與元數據一起存儲在注冊表中,元數據結構為 TrLV 記錄。證書本身存儲在記錄內部,類型為 0x20。
參考來源:
https://blog.nviso.eu/2019/08/28/extracting-certificates-from-the-windows-registry/