673 字
3 分鐘
pyHanko 為 PDF 做 PAdES 數位簽章 並以 OpenSSL 驗簽
2024-09-26
無標籤

過去我寫過一篇文章,關於說明如何用 Adobe Acrobat Reader 為 PDF 做數位簽章,而這個數位簽章屬於 PAdES,除了透過 Acrobat 進行驗簽外,也可以透過 pyHanko 進行驗簽,本文將透過 pyHanko 簽章與 OpenSSL 驗簽。


事前準備#

使用 pyHanko 在做數位簽章的過程,需要匯入憑證與私鑰,因此沒辦法用在自然人憑證做數位簽章,但可以用於驗簽。

1. 安裝 pyHanko#

簽章用到 python 的 pyHanko,要先安裝

Terminal window
pip3 install pyHanko

2. 安裝 pdfsig#

驗簽用到 pdfsig

Terminal window
# Ubunutu
apt-get install poppler-utils

3. 準備一組憑證 (cert.pem) 與私鑰 (key.pem)#

Terminal window
# 產生私鑰
openssl genpkey -algorithm RSA -out key.pem
# 產生憑證請求檔
openssl req -new -key key.pem -out request.csr
# 產生自簽憑證
openssl x509 -req -days 365 -in request.csr -signkey key.pem -out cert.pem

準備一個要做簽章的 PDF,這是我範例用的 example.pdf


產生數位簽章#

透過以下指令為 example.pdf 做數位簽章,並輸出 example_pades.pdf 包含 PAdes 數位簽章的 PDF。

pyhanko sign addsig --field Sig1 pemder --cert cert.pem --key key.pem \
--no-pass example.pdf example_pades.pdf

欄位說明

  • field:簽章欄位
  • cert:憑證路徑
  • key:私鑰路徑
  • no-pass:私鑰無密碼,預設會問你密碼

其他欄位參考官方文件


驗證數位簽章#

驗簽有兩個步驟,要分開驗證:

  1. 驗證簽章值
  2. 驗證憑證

1. 驗證簽章值#

透過以下指令為 example_pades.pdf 驗證數位簽章。

pdfsig example_pades.pdf

會產生如下面結果。

看到 Signature Validation: Signature is Valid. 代表有驗證簽章值成功

會看到 Certificate Validation: Certificate issuer is unknown. 是因為我們用自簽憑證,他無法識別,使用自然人憑證簽出的 PAdES 也會無法識別。

2. 驗證憑證#

驗證憑證可以透過 Adober Acrobat,參考本文。以下解說如何透過指令來驗證 PAdES。

要驗證憑證,要先取得憑證PAdES 需要經過一下步驟:

  1. 從 PDF 中提取 PKCS7 數位簽章
  2. 從 PKCS7 數位簽章中提取憑證
  3. 將憑證與根憑證、中繼憑證進行憑證鏈驗證

透過以下指令從 PDF 匯出 PKCS7 數位簽章,可以看到 PKCS7 數位簽章被匯出到 example_pades.pdf.sig0 檔案

pdfsig example_pades.pdf -dump

再來從 PKCS7 數位簽章中提取憑證,這裡輸出憑證為 cert_in_p7.pem

Terminal window
openssl pkcs7 -inform DER -in example_pades.pdf.sig0 -print_certs -out cert_in_p7.pem

透過以下指令可以查看憑證資訊

openssl x509 -in cert_in_p7.pem -text

再來就是驗證憑證鏈,這裡驗證對象輸入剛剛簽章用的憑證,憑證鏈驗證通過會顯示 OK。

openssl verify -CAfile cert.pem cert_in_p7.pem

以下為自然人憑證的驗證指令,驗證時候需要輸入 GRCA 根憑證MOICA 中繼憑證

openssl verify -CAfile GRCA2.cer -untrusted MOICA2.cer cert_in_p7.pem