在上一篇文章,我們已經實際操作過 PKCS#7,學會怎麼產生與使用。今天要進一步帶大家「拆解」這個封裝,理解它在 ASN.1 層級上的結構。只要看懂一次,下次遇到 PKCS#7 檔案就不再是黑盒子。
我這裡提供前文產生的document_attached.p7m
-----BEGIN PKCS7-----
MIIGIQYJKoZIhvcNAQcCoIIGEjCCBg4CAQExDzANBglghkgBZQMEAgEFADASBgkq
hkiG9w0BBwGgBQQDMTIzoIIDbzCCA2swggJToAMCAQICFC2VOJDiiljoadNUVXz+
8Q8MpwCxMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApT
b21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcN
MjUwOTI3MDc1NTIzWhcNMjYwOTI3MDc1NTIzWjBFMQswCQYDVQQGEwJBVTETMBEG
A1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg
THRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAinEJsiYwVXWlHOCz
CJEpWV73DqcNE/YQe6AIsX+e4niswPyjqv2eHRVEC/n6bVfyADlboRK//w4hzUUa
THH9tnuAXa/eOEqKcPTtT/pvaugSRnWTcf5KlTaNOfebtb+dSUwgpysH/k0cqRWw
twkSxkzCx70kzs6FbWqJjHHHFT3/JBSaX7u+qnaf+76/HH3MdphgTFMOhlMTiVo5
t4tui7F9/+aQHyi1kDjEPYNstB0+B41vlSo+OeH7+lja3JJWTzYMffUASuEO3RT1
2qSrhXtdknCErg0yjjUHx0hIuUWaHZMhMnvncXCJ0WEQagBUr4I04tzOingbP2kP
BLkVUQIDAQABo1MwUTAdBgNVHQ4EFgQUcOM5t29Ez9fIsoPPzwtJ8xmlZrgwHwYD
VR0jBBgwFoAUcOM5t29Ez9fIsoPPzwtJ8xmlZrgwDwYDVR0TAQH/BAUwAwEB/zAN
BgkqhkiG9w0BAQsFAAOCAQEAZceIxeXf+E17MUHbpmU5+V4EFwMNXgEP0UF6r3Gs
SAPXjO3EUqPJaZLXiuLfM9Lxe/3DTfzWf4F2shROo4z5F4lUTaFWBGbjj7m0cXP3
Pj49lrq4vvqbBehzNYmJX5yszGWEFbiy657Up13c+uHQFngbHVdMk0if0X2aJ14e
k4oQBbD986Er+O4Vq3XyRt0ACwfDJq1qIHaq3UQa2G5FKJRirYm9fqHpehjMFSJ6
jJ5hoDjYB/SXHq8DnD48pM7dgGkmVhx8t75DCJLdC17Ql8KYnIVr5d3xdPOeOzaz
4mrxqKJcEwxo1xJLYZIQKE7CXvmucoTFZLis5SegcOCq5jGCAm8wggJrAgEBMF0w
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZAIULZU4kOKKWOhp01RVfP7xDwynALEwDQYJ
YIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG
9w0BCQUxDxcNMjUwOTI3MDc1NzMxWjAvBgkqhkiG9w0BCQQxIgQgpmWkWSBCL51B
fkhn79xPuKBKHz//H6B+mY6G9/eieuMweQYJKoZIhvcNAQkPMWwwajALBglghkgB
ZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggq
hkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwIC
ASgwDQYJKoZIhvcNAQEBBQAEggEAFuUMOexbf5woCQTm3FeDTEMlW9tC0Q5dX+6g
XNbxPn2mBwUQNmUvj1d5rW/POEfgc78wxUrf+tb7QfreKg7eoStSxZMJS+kcdK4q
Nz4/XfNdqCptCpHLl6JtmzrP8PnoUKSEqcNMMTXhZtg1PJR2V+3Rxndtp9y/azD6
2F/cydANC8ZxQR3vVfmvrpR0O1s5DpOmx9JZKCneWP4JB4nXxVxIdpIwSH0QRpiD
Brqgy2HopO8JWvqu4T4PhDLT43Y8lWsQZArbhZ7I0LyIlqOr71evtxa2blIlTX6Y
JupDFfSKpo4nCFoAtnRUhlO3FZ8Ztr0LuAl00Kuz3HLsukJfTA==
-----END PKCS7-----
最外層的結構是 ContentInfo:
ContentInfo SEQUENCE
contentType OBJECT IDENTIFIER 1.2.840.113549.1.7.2 signedData (PKCS #7)
content [0]
這裡 contentType
OID 指定為 1.2.840.113549.1.7.2
,代表這是一個 signedData 封裝。
接下來進入 SignedData
:
SignedData SEQUENCE
version INTEGER 1
digestAlgorithms SET
algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256
1
。encapContentInfo SEQUENCE
eContentType OBJECT IDENTIFIER 1.2.840.113549.1.7.1 data (PKCS #7)
eContent OCTET STRING (3 byte) 123
data
。"123"
)。內嵌式簽章(p7m)才會有實際資料,分離式簽章(p7s)則無。certificate CertificateChoices SEQUENCE
tbsCertificate ...
signatureAlgorithm sha256WithRSAEncryption
signature BIT STRING ...
這裡包含了簽章所需的 X.509 憑證,內含:
sha256WithRSAEncryption
)SignerInfo SEQUENCE
version INTEGER 1
sid issuerAndSerialNumber
digestAlgorithm sha-256
signedAttributes
contentType (OID 1.2.840.113549.1.9.3)
signingTime (OID 1.2.840.113549.1.9.5)
messageDigest (OID 1.2.840.113549.1.9.4)
signatureAlgorithm rsaEncryption
signature OCTET STRING (256 byte)
逐項來看:
sid:簽章者身份,由「憑證序號 + 發行者」組成。
digestAlgorithm:再次宣告雜湊演算法(這裡仍是 SHA-256)。
signedAttributes:一些附加資訊,包括:
contentType
:指定簽的內容類型。signingTime
:簽章時間(例子裡是 2025-09-27 07:57:31 UTC
)。messageDigest
:簽章時的雜湊值。signatureAlgorithm:簽章演算法(這裡是 RSA)。
signature:簽章值(256 bytes 的 RSA 簽章)。
把上面的層次整理一下,一份 PKCS#7 signedData 檔案會包含:
ContentInfo:外層包裹,指定內容類型。
SignedData:簽章資料主體。
這樣逐層拆解之後,我們就能清楚掌握「簽章文件到底簽了什麼、誰簽的、怎麼簽的」。
土城好吃的滷肉飯,滷肉都是全肥,是我最愛這種,調味也很讚,好吃