python - 验证PE文件的签名

标签 python openssl certificate signature authenticode

我正在尝试使用 OpenSSL(或者实际上使用 Python,但 Python 在证书处理方面似乎很糟糕)来验证 PE 文件的证书/签名。

我已经从 PE 文件中提取了 DER PKCS7 证书,如下所述:http://blog.didierstevens.com/2008/01/11/the-case-of-the-missing-digital-signatures-tab/

并且我创建了一个没有校验和和签名数据的 PE 文件的修改版本,如下所述:http://www.mail-archive.com/cryptography@c2.net/msg04202.html

修改后的文件的sha1sum与证书中的sha1sum相同。

我尝试用 openssl 验证未签名的、修改过的 PE 文件:openssl smime -verify -in signature.der -content modified_executable.exe -inform DER -binary 但我只得到

Verification failure 140415508248232:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:342:Verify error:unsupported certificate purpose

如果我将 -noverify 添加到我得到的命令中

Verification failure 140595583981224:error:21071065:PKCS7 routines:PKCS7_signatureVerify:digest failure:pk7_doit.c:1097: 140595583981224:error:21075069:PKCS7 routines:PKCS7_verify:signature failure:pk7_smime.c:410:

我错过了什么?

最佳答案

假设:以下是在带有 OpenSSL 0.9.8e 的 Cygwin 上完成的

对于“不受支持的证书用途”,直接签名者可能没有 S/MIME 用途。

From OpenSSL documentation:
-purpose purpose
    the intended use for the certificate. Without this option no chain verification will be done.
$ openssl x509 -purpose -in goodcert.pem -noout
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : No
SSL server CA : No
Netscape SSL server : No
Netscape SSL server CA : No
S/MIME signing : No
S/MIME signing CA : No
S/MIME encryption : No
S/MIME encryption CA : No
CRL signing : No
CRL signing CA : No
Any Purpose : Yes
Any Purpose CA : Yes

With reference to this, I added the switch "-purpose any". Then I no longer see "unsupported certificate purpose" but still encounter same digest & signature failures as you.

1900:error:21071065:PKCS7 routines:PKCS7_signatureVerify:digest failure:pk7_doit.c:948:
1900:error:21075069:PKCS7 routines:PKCS7_verify:signature failure:pk7_smime.c:312:

With hints from this and lots of research(#1,#2), it turns out the input "modified_exe" to -content was wrong. It should have been the content field in the Sequence ContentInfo of the PKCS #7 SignedData, excluding its DER tag and length bytes.
Refer to Authenticode_PE.docx for the declaration of SignedData.
(simply too much details I don't see fit including!)

Check below for clarity:

openssl asn1parse -inform der -in signature.der > signature.txt
head signature.txt -n30
    0:d=0  hl=4 l=5464 cons: SEQUENCE          
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l=5449 cons: cont [ 0 ]        
   19:d=2  hl=4 l=5445 cons: SEQUENCE          //SignedData
   23:d=3  hl=2 l=   1 prim: INTEGER           :01 //Version
   26:d=3  hl=2 l=  11 cons: SET               //DigestAlgorithmIdentifiers
   28:d=4  hl=2 l=   9 cons: SEQUENCE          
   30:d=5  hl=2 l=   5 prim: OBJECT            :sha1
   37:d=5  hl=2 l=   0 prim: NULL              
   39:d=3  hl=2 l= 104 cons: SEQUENCE          //ContentInfo
   41:d=4  hl=2 l=  10 prim: OBJECT            :1.3.6.1.4.1.311.2.1.4 //ContentType
   53:d=4  hl=2 l=  90 cons: cont [ 0 ]        
   55:d=5  hl=2 l=  88 cons: SEQUENCE          //SpcIndirectDataContent (exclude this tag and length bytes)
   57:d=6  hl=2 l=  51 cons: SEQUENCE          //SpcAttributeTypeAndOptionalValue
   59:d=7  hl=2 l=  10 prim: OBJECT            :1.3.6.1.4.1.311.2.1.15 //ObjectID
   71:d=7  hl=2 l=  37 cons: SEQUENCE          
   73:d=8  hl=2 l=   1 prim: BIT STRING        
   76:d=8  hl=2 l=  32 cons: cont [ 0 ]        
   78:d=9  hl=2 l=  30 cons: cont [ 2 ]        
   80:d=10 hl=2 l=  28 prim: cont [ 0 ]        
  110:d=6  hl=2 l=  33 cons: SEQUENCE          //DigestInfo
  112:d=7  hl=2 l=   9 cons: SEQUENCE          //AlgorithmIdentifier
  114:d=8  hl=2 l=   5 prim: OBJECT            :sha1 //ObjectID
  121:d=8  hl=2 l=   0 prim: NULL              
  123:d=7  hl=2 l=  20 prim: OCTET STRING      [HEX DUMP]:<hash of modified_exe> //digest OCTETSTRING
  145:d=3  hl=4 l=4774 cons: cont [ 0 ]        
  149:d=4  hl=4 l=1332 cons: SEQUENCE          
  153:d=5  hl=4 l= 796 cons: SEQUENCE          
  157:d=6  hl=2 l=   3 cons: cont [ 0 ]        
  159:d=7  hl=2 l=   1 prim: INTEGER           :02

从偏移量 57144 的字节流是 -content 的正确输入!
确切的偏移量取决于您的文件。
作为粗略的指导,“1.3.6.1.4.1.311.2.1.15”前两行是“SpcIndirectDataContent”,这一行注意55+2+88-1=144。下一行从 57 开始。

最终命令:

openssl smime -verify -inform DER -in signature.der -binary -content signedData -CAfile myCA.crt -purpose any -out tmp

关于python - 验证PE文件的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22370949/

相关文章:

python - Google 自定义设备操作在 Raspberry Pi Google Assistant 上出现错误

python - 如何为 Python 安装 OpenSSL

php - 如何检查安装的 OpenSSL 版本是否 >= 0.9.8k

ssl - 如何使用 lighttpd 网络服务器限制 SSL 片段大小?

clickonce - 代码签名需要什么证书?

WCF 证书链信任身份验证 : "The caller was not authenticated by the service."

python - Python 中的 Lambda 和函数

python - pygame-永久调整主音量

python - 在 sklearn.decomposition.PCA 中,为什么 components_ 是负的?

wcf - 在 XP SP3 上使用 SSL 的自承载 WCF 服务