验证PE文件的签名

时间:2014-03-13 06:39:59

标签: python openssl certificate signature authenticode

我正在尝试使用OpenSSL(或实际上使用Python来验证PE文件的证书/签名,但看起来Python很糟糕,关于证书处理)。

我已从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但我只能

  

验证失败   140415508248232:错误:21075075:PKCS7例程:PKCS7_verify:证书验证错误:pk7_smime.c:342:验证错误:证书目的不受支持

如果我将-noverify添加到命令我只是

  

验证失败   140595583981224:错误:21071065:PKCS7例程:PKCS7_signatureVerify:摘要失败:pk7_doit.c:1097:   140595583981224:错误:21075069:PKCS7例程:PKCS7_verify:签名失败:pk7_smime.c:410:

我错过了什么?

4 个答案:

答案 0 :(得分:1)

假设:以下是使用OpenSSL 0.9.8e对Cygwin进行的

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

来自OpenSSL documentation
- 用途
证书的预期用途。如果没有此选项,则不会进行链验证。
$ 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

参考this,我添加了开关“-purpose any”。然后我不再看到“不支持的证书目的”,但仍然遇到相同的摘要&签名失败就像你一样。

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:

来自this的提示和大量研究(#1#2),结果输入“modified_exe”到-content是错误的。它应该是PKCS#7 SignedData 的序列 ContentInfo 中的内容字段,不包括其DER标记和长度字节。
有关签名数据的声明,请参阅Authenticode_PE.docx (太多细节我认为不合适包括!)

请在下面查看清晰度:

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

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

最终的cmd:

  

openssl smime -verify -inform DER -in signature.der -binary -content   signedData -CAfile myCA.crt - 用于任何-out tmp

答案 1 :(得分:0)

  

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

为什么不使用微软发布的格式?没有必要采用逆向工程。


  

我错过了什么?

PE / PE +可执行文件的部分文件已签名,而不是整个文件。在摘要数据时,您必须省略OptionalHeader中的校验和,省略Data Directory中的证书表,并省略Attribute Certificate Table部分。

以下是您可能想要熟悉的两个参考资料:

要省略的部分显示在Windows Authenticode Portable Executable Signature Format,第6页。其转载如下。

enter image description here


如果您需要以编程方式处理PE文件格式的帮助,请参阅MSDN杂志中的Matt Pietrek的An In-Depth Look into the Win32 Portable Executable File Format

答案 2 :(得分:0)

  

修改后的文件的哈希值与提取的证书中的哈希值相同

我的坏。我错过了那一部分。

这是pk7_smime.c失败的地方。它的行i = X509_verify_cert

i = X509_verify_cert(&cert_ctx);
if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx);
X509_STORE_CTX_cleanup(&cert_ctx);
if (i <= 0) {
    PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR);
    ERR_add_error_data(2, "Verify error:",
        X509_verify_cert_error_string(j));
    sk_X509_free(signers);
    return 0;
}

X509_verify_cert位于第150行的<openssl dir>/crypto/x509/x509_vfy.c内。它的功能相当大(大约250行),因此您可能需要完成它。

在您执行此功能之前,您可以尝试将-signer选项添加到openssl smime功能。这可能是一个简单的修复。请参阅simime(3)上的OpenSSL文档。

我不知道从哪里获得签名证书,因为它不在我面前,搜索“Microsoft Code Signing CA”会产生太多噪音。转储最终实体证书,找到发行者,然后搜索发行人的名称。

答案 3 :(得分:0)

  

验证失败140415508248232:错误:21075075:PKCS7例程:PKCS7_verify:certificate   验证错误:pk7_smime.c:342:验证错误:证书目的不受支持

正如@guest已经指出的那样,OpenSSL具有&#34;功能&#34;在验证smime(或cms)时:它的行为就像传递了-purpose smimesign一样。详情请here

如果您的签名证书与OpenSSL的smimesign&#34;目的&#34;不兼容(请参阅man x509CERTIFICATE EXTENSIONS部分列出&#34;目的&#34;),然后您必须使用-purpose any禁用扩展程序检查(并与其他人核对)如果您的政策要求,则可以发挥作用。

  

如果我将-noverify添加到命令

你可能不想这样做。此选项会禁用签名者证书上的任何检查。