ITextSharp Document Signing showing invalid

时间:2015-11-12 11:20:07

标签: pdf itextsharp itext signing

So I've been working on signing of PDF documents lately, and today I came across a new and wonderful problem. So when I sign the document(The document is signed on a server actually) and open that document up in my machine, the signature shows valid and that it is LTV enabled, so pretty much works as expected. But when I open the same document on my boss's computer it shows that the identity of the signing could not be verified even after the certificate was trusted, but if I open the certificate properties it says that the certificate is valid and revocation was performed successfully. What could be the cause of this?

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

Figure 1: The certificate itself is trusted.

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

Figure 2: Intermediary certificate is trusted.

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

Figure 3: Root certificate trusted

Signed Document: https://drive.google.com/file/d/0B9RyqgJoa6W8WlBLemVETXJRU0U/view?usp=sharing

Another weird thing, for the timestamping signature, when I add the Root certificate as a trusted root certificate to adobe, it says that LTV is not enabled, but if I add the GlobalTrustFinder certificate itself as a trusted certificate it says that LTV is enabled. Any reason that it would do that?

Any help would really be appreciated

Code for adding LTV to the existing signature blocks as well as add the timestamping signature:

private void SignDocumentSigningBlockAddLTVVerification(PdfStamper stamper, Certificate certificate)
    {
        LtvVerification ltvVerification = stamper.LtvVerification;
        List<string> signatureFieldNames = stamper.AcroFields.GetSignatureNames();
        ITSAClient tsaClient = new TSAClientBouncyCastle(_settingManager["DocumentSigningTimestampingServiceAddress"], String.Empty, String.Empty, Int32.Parse(_settingManager["DocumentSigningEstimatedTimestampSize"]), _settingManager["DocumentSigningEncryptionHashAlgorithm"]);
        IOcspClient ocspClient = new OcspClientBouncyCastle();
        ICrlClient crlClient = new CrlClientOnline(SignDocumentSigningBlockBuildChain(new X509Certificate2(certificate.Bytes, certificate.Password, X509KeyStorageFlags.Exportable)).ToList());

        PdfPKCS7 pkcs7 = stamper.AcroFields.VerifySignature(signatureFieldNames.Last());
        if (pkcs7.IsTsp)
        {
            ltvVerification.AddVerification(signatureFieldNames.Last(), ocspClient, crlClient, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
        }
        else
        {
            foreach (string name in stamper.AcroFields.GetSignatureNames())
            {
                ltvVerification.AddVerification(name, ocspClient, crlClient, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
            }
        }
        ltvVerification.Merge();

        PdfSignatureAppearance appearance = stamper.SignatureAppearance;
        LtvTimestamp.Timestamp(appearance, tsaClient, null);
    }

Kind regards

1 个答案:

答案 0 :(得分:2)

无法检查吊销

  

但是,当我在老板的计算机上打开相同的文档时,它表明即使在证书被信任之后也无法验证签名的身份,但是如果我打开证书属性,则表明证书是有效和撤销成功执行。可能是什么原因造成的?

由于我无法检查你老板的电脑,这肯定是猜测。所以......

给它一个镜头

您说证书是受信任的但涉及的证书很多。那么,你信任哪一个?根据你的截图

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

信任用户证书(如果你有,那么该证书不会针对CRL进行检查,而是在未经进一步测试的情况下被信任)。

您可能信任老板计算机上的根CA证书。如果您有,则不仅要检查最终用户证书是否需要撤销,还要检查中间CA证书(SAPO Class) 4 CA)!可能这就是你的问题出现的地方

因此,当您在撤销选项卡上时,请选择中间证书并查看是否可以执行撤销检查。如果没有,那就是你遇到的问题。

PS:不是这样

OP测试了上面提到的想法但是

  

所以我回去检查了所有证书,似乎按预期执行了CRL检查。

因此,它并不像我想象的那么容易

  

设置的不同之处在于我信任我签署的证书作为根证书因此显示为在我的计算机上成功签名,我现在设置了我的安全设置,以便我得到相同的结果就像我老板的电脑一样。

好的,所以解释了这两台计算机上的结果之间的差异。

要确定问题是在确定CA证书或用户证书的撤销状态,是否可以再次重新配置您的设置并信任CA证书?

如果在此更改后问题仍然存在,则问题很可能与您的用户证书相关联并检查其撤销状态。如果它消失,则问题很可能与检查CA证书的撤销状态有关。

  

我现在信任CA,它仍然有同样的问题,但如果我信任用户证明标记&#34;将此证书用作受信任的根&#34;和认证文件&#34;复选框,签名显示为有效以及启用LTV,但仅当我将其标记为根时。在所有其他情况下,签名都有警告,指出未执行撤销检查。

如果您立即信任您的用户证书,则会毫不费力地验证签名。毕竟,你确实相信证书......

将它放在一边,检查用户证书时已经出现问题。我会尝试再研究一下。

PPS:这就是为什么......

如果所有其他方法都失败了,请开始检查签名或者我认为在证书中找不到任何非常糟糕的内容之后我想到了。我在ASN.1转储实用程序中打开了签名并且......

...
    <30 42>
2174   66:             SEQUENCE {
    <06 09>
2176    9:               OBJECT IDENTIFIER '1 2 840 113583 1 1 8'
    <31 35>
2187   53:               SET {
    <30 33>
2189   51:                 SEQUENCE {
    <A0 31>
2191   49:                   [0] {
    <30 2F>
2193   47:                     SEQUENCE {
    <2D 2D>
2195   45:                       Unknown (Reserved) {
    <2D 2D>
2197   45:                         Unknown (Reserved) {
    <2D 42>
2199   66:                           Unknown (Reserved) {
    <45 47>
2201   71:                             [APPLICATION 5]
         :                   'IN X509 CRL-----.MIIfZzCCHU8CAQEwDQYJKo0...*.H..'
         :                   '............0...Ix<..N+'
         :                   Error: IA5String contains illegal character(s).
Error: Inconsistent object length, 7 bytes difference.
         :                             }
Error: Inconsistent object length, 30 bytes difference.
         :                           }
Error: Inconsistent object length, 32 bytes difference.
         :                         }
Error: Inconsistent object length, 32 bytes difference.
         :                       }
Error: Inconsistent object length, 32 bytes difference.
         :                     }
Error: Inconsistent object length, 32 bytes difference.
         :                   }
Error: Inconsistent object length, 32 bytes difference.
         :                 }
Error: Inconsistent object length, 32 bytes difference.
         :               }
Error: Inconsistent object length, 32 bytes difference.
         :             }
...

因此签名本身存在语法错误,更确切地说是 PDF签名证书吊销信息属性(OID 1 2 840 113583 1 1 8)。

(用不同的观察者查看该区域,可以看到有一个文本(!)&#34; ----- BEGIN X509 CRL -----&#34; - 似乎有一个文本CRL表示在这里无效。)

因此,Adobe Reader在签名验证期间尝试检查证书撤销时,检查签名属性,该属性可用于在签名期间添加吊销信息,查找损坏的属性值并且似乎停止验证检查失败...

用于填写证书详细信息窗口的代码似乎是单独编码的。

为什么?

有人可能想知道您的签名的 PDF签名证书吊销信息属性中是否包含了文本CRL表示。

我调查了嵌入式&#34; CRL&#34;。它采用PEM格式,在47个字节后被切断。所以我在证书(https://pki.trustcentre.co.za/crl/sapo_c4ca.crl)中给出的URL处访问了CRL,我确实检索了一个PEM格式的(完整的)CRL文本。签名创建代码似乎试图按原样包含它,但它已经完成了。

PKI是否以PEM格式而不是DER格式提供CRL是错误的?或者假设在指向的位置找到DER编码的CRL时签名创建代码是错误的吗?

Internet X.509公钥基础结构证书和证书吊销列表(CRL)配置文件RFC 5280)的当前规范指定:

  

当使用HTTP或FTP URI方案时,URI必须指向[RFC2585]中指定的单个DER编码的CRL。

     

Section 4.2.1.13. CRL Distribution Points

但它并没有说出任何与HTTPS URI方案相同的内容!

因为PKI采用HTTPS方案,因此PKI可能被认为符合RFC的字母。

尽管HTTPS方案本质上只是HTTP方案的安全变体,因此PKI明确且不必要地违反了RFC的精神,但它似乎并没有违反它的字母。

因此,CRL检索类(如iText&#39; s CrlClientOnline)最好检查检索到的CRL的格式,并在必要时对其进行转换。

LTV启用或未启用LTV

解释

  

另一个奇怪的是,对于时间戳签名,当我将根证书作为受信任的根证书添加到adobe时,它表示LTV未启用,但如果我将GlobalTrustFinder证书本身添加为可信证书,则表示LTV已启用。有什么理由会这样做吗?

这很明显:

如果您信任根证书,则必须检查中间CA和最终实体证书的吊销。由于您的文档中没有嵌入CRL或OCSP响应,因此您的时间戳不支持LTV。

另一方面,如果您明确信任最终实体证书,即创建时间戳的证书,Adobe验证器会立即信任时间戳。无需检查明确信任的证书的撤销...因此,在这种情况下,时间戳是LTV启用的。

(术语&#34; LTV启用&#34;是一个具有非常可变值的Adobe术语。对于此术语的背景和其他LTV相关术语,请参阅{em>背景部分{ {3}}以及从那里引用的其他答案,)

后续问题

  

对于时间戳,我有点困惑,我按照你推荐的帖子中的代码示例,我使用的代码是一个变体,但原则上相同,为什么CRL和OCSP响应没有嵌入?

重大差异this answer中的代码不应用文档时间戳,它只是添加了验证相关信息(证书,CRL,OCSP)响应)。

Adob​​e的专有术语&#34; LTV启用&#34; 是指文件签名或文档时间戳,其中包含验证相关签名(包括签署CRL,OCSP响应和验证过程中使用的时间戳的签名)都包含在PDF&#34;中。添加验证相关信息后,您的代码会添加文档时间戳,因此验证该时间戳所需的信息通常在PDF中不可用。

ETSI的标准化术语&#34;带有LTV&#34; 的PDF文档是指带有验证相关信息的签名PDF(例如&#34; LTV启用&#34; PDF)加上最终文档时间戳。

您使用的iText示例代码尝试使用LTV&#34;创建ETSI&#34; PDF文档。因此,必须进行调整,而不是尝试创建一个PDF,其中所有文档签名和时间戳都是Adobe&#34; LTV启用&#34;。

  

至于添加crls和ocsps,据我所知,添加LTV,你必须将验证添加到文档中的所有签名和最终文档时间戳,就像我在我提供的代码中所做的那样,不是这样吗?

在LTV的上下文中有不同的用例,并且根据一个非常用例,可能必须添加不同的信息。