[Mac/Linux] 使用 openssl asn1parse 檢視 PKCS7 簽章檔案的內容
今天在查一個 openssl 簽章 (sign) 的問題…
我手上有一個 checksum 檔案:
sha256sum * > checksum
然後專案會再對這個檔案簽章 (細節不在我們管轄範圍),
產生一個 checksum.p7 檔案。
然後專案程式會檢查這個 checksum.p7 檔案是否正確,
確認簽章正確後,就能再檢查 checksum 的內容是否符合:
sha256sum -c checksum
上面的機制基本運作正常,不過今天卻突然出現,
舊有的程式在驗證新產生的簽章時,產生錯誤:
x509: certificate signed by unknown authority
這真的有點奇怪,因為我用 使用 OpenSSL 檢查簽章內容與有效日期 這裡的方法,
取出 checksum.p7 裡的憑證 (certificate):
$ openssl cms -verify -binary -in checksum.p7 -inform DER -verify -content checksum -purpose any -certsout need_to_check.certs 0b86b80a1422cf527b878abb6c576f4ea4ffb6fa293b187d70a060ab210c7b50 ./program 9797a360ce336513e6b5443270f5ba54ffe7ae8845abcfe888efa4f7003fb5a0 ./README 381cedd007a4eaf38c6e9d85241512f9a5c0ebe15cee178db1271129eec54d50 ./manifest Verification successful
openssl 驗證成功,而取出來的簽章存在 need_to_check.certs 檔案裡面,
再用下面這個指令,檢查憑證的內容:
openssl crl2pkcs7 -nocrl -certfile need_to_check.certs | openssl pkcs7 -print_certs -text -noout
可以看到裡面分別有一張中間憑證 (Intermediate CA certificate)
DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1,
和一張簽給 My Company 的最終憑證 :
Signature Algorithm: sha384WithRSAEncryption Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4 Validity Not Before: Apr 29 00:00:00 2021 GMT Not After : Apr 28 23:59:59 2036 GMT Subject: C=US, O=DigiCert, Inc., CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1 ...... Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, O=DigiCert, Inc., CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1 Validity Not Before: Jul 27 00:00:00 2021 GMT Not After : Oct 25 23:59:59 2022 GMT Subject: businessCategory=Private Organization/jurisdictionC=TW/C=TW, ST=Taipei City, O=My Company, Inc.
而這 need_to_check.certs 檔案的內容,
不管是從舊版或是新版簽章出來的 checksum.p7,
拿出來長得都一樣,也就是說都是用一樣的憑證在簽發的,
為什麼會有舊版程式無法驗證新版簽章的問題呢?
後來同事又提了一個指令,是用 openssl asn1parse
來檢視這個 .p7 檔案。
我不知道 ASN.1 是什麼結構,不過看來這個指令可以將細節資訊都印出來,
不像前面的幾個指令,似乎只取出了比較重要的資訊。
$ openssl asn1parse -inform DER -in checksum.p7 0:d=0 hl=4 l=9010 cons: SEQUENCE 4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData ...... 175:d=9 hl=2 l= 3 prim: OBJECT :commonName 180:d=9 hl=2 l= 24 prim: PRINTABLESTRING :DigiCert Trusted Root G4 ...... 282:d=9 hl=2 l= 3 prim: OBJECT :commonName 287:d=9 hl=2 l= 56 prim: PRINTABLESTRING :DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1 ...... 4762:d=17 hl=2 l= 3 prim: OBJECT :commonName 4767:d=17 hl=2 l= 50 prim: PRINTABLESTRING :DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA ...... 4895:d=17 hl=2 l= 3 prim: OBJECT :commonName 4900:d=17 hl=2 l= 27 prim: PRINTABLESTRING :DigiCert Timestamp 2022 - 2 ......
從上面的結果裡,和之前 checksum.p7 結果比較,
發現之前的 Timestamping Intermediate CA 是 DigiCert SHA2 Assured ID Timestamping CA,
但現在換成了 DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA…
- DigiCert SHA2 Assured ID Timestamping CA
- 上層是 DigiCert Assured ID Root CA (這個我們有存)
- DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA 的上層
- 上層是 DigiCert Trusted Root G4 (這個我們沒有存)
猜想就是因為 Timestamping CA 改變,而我們又沒有存 Timestamping 的 Root CA 憑證,
導致驗證憑證鍊 (certificate chain) 時,發生錯誤,
而出現 certificate signed by unknown authority 的問題…
理論上,將 DigiCert Trusted Root G4 加進程式中,
就可以驗證新的簽章了,事實也是如此。
但問題還沒有完全解決,
因為舊版程式無法驗證含有這新的 Timestamping CA 的簽章檔案,
所以會拒絕升級成為新版… 這可是大麻煩了…
參考資料:Ubuntu Manpage: asn1parse – ASN.1 parsing tool