Security pdf完整性验证失败

Security pdf完整性验证失败,security,pdf,pkcs#7,Security,Pdf,Pkcs#7,我试图通过bash命令验证pdf文件的完整性 使用dd,我提取了pdf的signedContent和pkcs7分离对象 然后我通过 xxd -r -p pkcs7_extracted > pkcs7_extracted.bin openssl asn1parse -inform DER <pkcs7_extracted.bin >pkcs7_extracted_decoded 我特别注意到messageDigest字段等于使用ByteRange获得的signedConten

我试图通过bash命令验证pdf文件的完整性

使用dd,我提取了pdf的signedContent和pkcs7分离对象

然后我通过

xxd -r -p pkcs7_extracted > pkcs7_extracted.bin

openssl asn1parse -inform DER <pkcs7_extracted.bin >pkcs7_extracted_decoded
我特别注意到messageDigest字段等于使用ByteRange获得的signedContent的计算摘要

我提取了加密的散列,用公钥解密,然后用asn1命令再次解码

dd if=pkcs7_extracted.bin of=extracted.sign.bin bs=1 skip=$[ 5242 + 4 ] count=256

#decrypt

openssl rsautl -verify -pubin -inkey publickey.pem < extracted.sign.bin > verified.bin

#decode of result
openssl asn1parse -inform der -in verified.bin
我非常确定解密是有效的,因为该对象被正确解码,并且正如我所期望的那样包含一个sha256对象,但是正如您所看到的,摘要值是不同的

我找错地方了吗?我不知道如何验证完整性

此外,Acrobat当然会验证此签名文档的完整性


提前谢谢 是当前PDF规范ISO 32000-1中引用的RFC;因此,即使已被淘汰,更新的RFC中的更改也可能不适用于这种情况

  SignedData ::= SEQUENCE {
    version CMSVersion,
    digestAlgorithms DigestAlgorithmIdentifiers,
    encapContentInfo EncapsulatedContentInfo,
    certificates [0] IMPLICIT CertificateSet OPTIONAL,
    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
    signerInfos SignerInfos }

...

  SignerInfo ::= SEQUENCE {
    version CMSVersion,
    sid SignerIdentifier,
    digestAlgorithm DigestAlgorithmIdentifier,
    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
    signatureAlgorithm SignatureAlgorithmIdentifier,
    signature SignatureValue,
    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

...

  SignedAttributes ::= SET SIZE (1..MAX) OF Attribute

...

  signedAttrs is a collection of attributes that are signed.  The
  field is optional, but it MUST be present if the content type of
  the EncapsulatedContentInfo value being signed is not id-data.
  SignedAttributes MUST be DER encoded, even if the rest of the
  structure is BER encoded.  Useful attribute types, such as signing
  time, are defined in Section 11.  If the field is present, it MUST
  contain, at a minimum, the following two attributes:

     A content-type attribute having as its value the content type
     of the EncapsulatedContentInfo value being signed.  Section
     11.1 defines the content-type attribute.  However, the
     content-type attribute MUST NOT be used as part of a
     countersignature unsigned attribute as defined in section 11.4.

     A message-digest attribute, having as its value the message
     digest of the content.  Section 11.2 defines the message-digest
     attribute.

...

  The result of the message digest calculation process depends on
  whether the signedAttrs field is present.  When the field is absent,
  the result is just the message digest of the content as described
  above.  When the field is present, however, the result is the message
  digest of the complete DER encoding of the SignedAttrs value
  contained in the signedAttrs field.  Since the SignedAttrs value,
  when present, must contain the content-type and the message-digest
  attributes, those values are indirectly included in the result.
因此,你的观察

messageDigest字段等于使用ByteRange获得的signedContent的计算摘要

指示正确的数据已签名,因为消息摘要属性的值应为内容的消息摘要

但正如您在这里也可以看到的,由您解密的实际内部签名字节签名的数据不是内容的消息摘要,而是签名的属性集合ttr

因此,您不能根据内容哈希验证这些签名字节,而是根据RFC中描述的已签名属性哈希验证这些签名字节

PS:OP同时可以在CMS签名数据验证主题上找到,该主题还说明了如何更形象地识别哪些属性已签名,哪些未签名

PPS:OP通过解密签名字节、提取包含的哈希并将其与实际哈希进行比较来验证。这对于基于RSA的签名是可以的。但是,基于DSA或ECDSA的签名无法解密,因此无法提取哈希值。必须使用特殊的验证例程进行验证


购买力平价:有不同风格的集成PDF签名。虽然这里使用的样式PKCS7/CADES是最常用和推荐的样式,但在一般的解决方案中,必须事先检查并验证。

请注意,在SigNeDATA对象中,有多个散列值要考虑,一般不相等。非常感谢!为了完成答案,我将链接到,以了解哪些是签名属性。
0:d=0  hl=2 l=  49 cons: SEQUENCE          
2:d=1  hl=2 l=  13 cons: SEQUENCE          
4:d=2  hl=2 l=   9 prim: OBJECT            :sha256
15:d=2  hl=2 l=   0 prim: NULL              
17:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:EBAA31519CD0CCA793FEC34AA6BDD8DFA5E4D5F63BA4711F6C8ECE5D20FEF393
  SignedData ::= SEQUENCE {
    version CMSVersion,
    digestAlgorithms DigestAlgorithmIdentifiers,
    encapContentInfo EncapsulatedContentInfo,
    certificates [0] IMPLICIT CertificateSet OPTIONAL,
    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
    signerInfos SignerInfos }

...

  SignerInfo ::= SEQUENCE {
    version CMSVersion,
    sid SignerIdentifier,
    digestAlgorithm DigestAlgorithmIdentifier,
    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
    signatureAlgorithm SignatureAlgorithmIdentifier,
    signature SignatureValue,
    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

...

  SignedAttributes ::= SET SIZE (1..MAX) OF Attribute

...

  signedAttrs is a collection of attributes that are signed.  The
  field is optional, but it MUST be present if the content type of
  the EncapsulatedContentInfo value being signed is not id-data.
  SignedAttributes MUST be DER encoded, even if the rest of the
  structure is BER encoded.  Useful attribute types, such as signing
  time, are defined in Section 11.  If the field is present, it MUST
  contain, at a minimum, the following two attributes:

     A content-type attribute having as its value the content type
     of the EncapsulatedContentInfo value being signed.  Section
     11.1 defines the content-type attribute.  However, the
     content-type attribute MUST NOT be used as part of a
     countersignature unsigned attribute as defined in section 11.4.

     A message-digest attribute, having as its value the message
     digest of the content.  Section 11.2 defines the message-digest
     attribute.

...

  The result of the message digest calculation process depends on
  whether the signedAttrs field is present.  When the field is absent,
  the result is just the message digest of the content as described
  above.  When the field is present, however, the result is the message
  digest of the complete DER encoding of the SignedAttrs value
  contained in the signedAttrs field.  Since the SignedAttrs value,
  when present, must contain the content-type and the message-digest
  attributes, those values are indirectly included in the result.
 5178:d=6  hl=2 l=  47 cons: SEQUENCE          
 5180:d=7  hl=2 l=   9 prim: OBJECT            :messageDigest
 5191:d=7  hl=2 l=  34 cons: SET               
 5193:d=8  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:18B399D208A08815DDF23C93B1B63B13757A6AA24B1932569D7A69D0DB3A34C2