数字签名(PKCS#7 - 延期签名)/自应用签名后文档已被更改或损坏 [英] Digital Signature (PKCS#7 - Deferred Signing) / The document has been altered or corrupted since the signature was applied

查看:4115
本文介绍了数字签名(PKCS#7 - 延期签名)/自应用签名后文档已被更改或损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



基本上,我的应用程序使用<$ c $标记pdf文档c> PKCS#7 由远程Web服务创建的签名。

我的应用程序发送这个Web服务的原始文件的哈希值(添加空签名字段后的可签名字节的哈希),并接收Base64编码的签名文件。

我将此签名嵌入到之前生成的具有空签名字段的临时pdf文件中。



最后,我的签名未经验证,因为Adobe Reader表示文档已更改或已损坏。



代码添加空签名字段并获取Pdf的可签名字节

  public static string GetBytesToSign (字符串unsignedPdf,字符串tempPdf,字符串signatureFieldName)
{
if(File.Exists(tempPdf))
File.Delete(tempPdf);

using(PdfReader reader = new PdfReader(unsignedPdf))
{
using(FileStream os = File.OpenWrite(tempPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader,os,'\0');
PdfSignatureAppearance外观= stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(36,748,250,400),1,signatureFieldName);

IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE,PdfName.ADBE_PKCS7_DETACHED);

MakeSignature.SignExternalContainer(appearance,external,8192);

byte [] array = SHA256Managed.Create()。ComputeHash(appearance.GetRangeStream());

return Convert.ToBase64String(array);
}
}
}

由于此操作生成 tempPdf ,我从这个 tempPdf 文件接收到pdf文档的可标记字节的散列。



然后使用下面的代码,我重新打开这个tempFile并嵌入Base64编码的 PKCS#7 签名。



代码打开Temp Pdf并嵌入接收的签名

 <$ c 
$ b byte [] signedBytes = Convert.FromBase64String(signature); $ c $ public static void EmbedSignature(string tempPdf,string signedPdf,string signatureFieldName,string signature)

使用(PdfReader reader = new PdfReader(tempPdf))
{
using(FileStream os = File.OpenWrite(signedPdf))
{
IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(reader,signatureFieldName,os,external);
}
}
}

由于此操作我生成了最后的 signedPdf 。但是,Adobe表示,由于更改或损坏,签名无效。









我真的被困在这一点上。我不知道我应该在哪里看下。

解决方案

在您从Web服务收到的签名中,有:

  39 59:。 。 。 SEQUENCE {
41 9:。 。 。 。 OBJECT IDENTIFIER data(1 2 840 113549 1 7 1)
:。 。 。 。 。 (PKCS#7)
52 46:。 。 。 。 [0] {
54 44:。 。 。 。 。 OCTET STRING
:。 。 。 。 。 。 7A 39 71 49 79 76 74 70 z9qIyvtp
:。 。 。 。 。 。 34 63 52 42 5A 31 53 53 4cRBZ1SS
:。 。 。 。 。 。 43 51 2B 50 30 4A 56 52 CQ + P0JVR
:。 。 。 。 。 。 69 6E 7A 35 6C 76 6A 59 inz5lvjY
:。 。 。 。 。 。 6A 58 6B 33 4C 37 59 50 jXk3L7YP
:。 。 。 。 。 。 2F 49 45 3D / IE =
:。 。 。 。 。 }
:。 。 。 。 }
[...]
1955 9:。 。 。 。 。序列{
1957 5:。 。 。 。 。 。 OBJECT IDENTIFIER sha1(1 3 14 3 2 26)
:。 。 。 。 。 。 。 (OIW)
1964 0:。 。 。 。 。 。 NULL
:。 。 。 。 。 。 }
1966 93:。 。 。 。 。 [0] {
1968 24:。 。 。 。 。 。 SEQUENCE {
1970 9:。 。 。 。 。 。 。 OBJECT IDENTIFIER contentType(1 2 840 113549 1 9 3)
:。 。 。 。 。 。 。 。 (PKCS#9)
1981 11:。 。 。 。 。 。 。 SET {
1983 9:。 。 。 。 。 。 。 。 OBJECT IDENTIFIER data(1 2 840 113549 1 7 1)
:。 。 。 。 。 。 。 。 。 (PKCS#7)
:。 。 。 。 。 。 。 。 }
:。 。 。 。 。 。 。 }
1994 28:。 。 。 。 。 。序列{
1996 9:。 。 。 。 。 。 。 OBJECT IDENTIFIER signingTime(1 2 840 113549 1 9 5)
:。 。 。 。 。 。 。 。 (PKCS#9)
2007 15:。 。 。 。 。 。 。 SET {
2009 13:。 。 。 。 。 。 。 。 UTCTime 22/09/2017 13:18:38 GMT
:。 。 。 。 。 。 。 。 }
:。 。 。 。 。 。 。 }
2024 35:。 。 。 。 。 。 SEQUENCE {
2026 9:。 。 。 。 。 。 。 OBJECT IDENTIFIER messageDigest(1 2 840 113549 1 9 4)
:。 。 。 。 。 。 。 。 (PKCS#9)
2037 22:。 。 。 。 。 。 。 SET {
2039 20:。 。 。 。 。 。 。 。 OCTET STRING
:。 。 。 。 。 。 。 。 。 EF 37 38 3B B1 31 AB 96 .78; .1 ..
:。 。 。 。 。 。 。 。 。 CE FC 47 1E 32 A7 79 73 ..G.2.ys
:。 。 。 。 。 。 。 。 。 5D 95 15 04] ...
:。 。 。 。 。 。 。 。 }
:。 。 。 。 。 。 。 }
:。 。 。 。 。 。 }
2061 13:。 。 。 。 。 SEQUENCE {
2063 9:。 。 。 。 。 。 OBJECT IDENTIFIER rsaEncryption(1 2 840 113549 1 1 1)
:。 。 。 。 。 。 。 (PKCS#1)
2074 0:。 。 。 。 。 。 NULL
:。 。 。 。 。 。 }

这里,您的base64编码哈希显示为嵌入的签名数据(偏移量56..99)。此外,哈希算法被选为SHA-1(偏移1955..1965),签名文档哈希是一个20字节的值,它与SHA-1哈希值的大小相匹配。此外,RSA还用于PKCS#11.5(偏移2061..2075)中描述的签名。



因此,它看起来像您的签名服务不会将您的输入用作base64编码的预先计算的文档哈希值,但作为普通数据使用SHA1withRSA / 2048签名。



所以错误不在iText中使用代码,而是在您的签名服务调用代码。


I have gone through all similar questions but could not find a case where itextsharp deferred signing is applied.

Basically, my application signs pdf documents using PKCS#7 signature that is created by remote web service.

My application sends this web service the hash of the original document (hash of the signable bytes after empty signature field is added), and receives a Base64 encoded signature file.

I embed this signature to previously generated temporary pdf file which has empty signature field.

At the end my signature is not validated because Adobe Reader says that either the document is changed or it is corrupted.

Code That Adds Empty Signature Field and Gets Signable Bytes of Pdf

public static string GetBytesToSign(string unsignedPdf, string tempPdf, string signatureFieldName)
{
    if (File.Exists(tempPdf))
        File.Delete(tempPdf);

    using (PdfReader reader = new PdfReader(unsignedPdf))
    {
        using (FileStream os = File.OpenWrite(tempPdf))
        {
            PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
            PdfSignatureAppearance appearance = stamper.SignatureAppearance;
            appearance.SetVisibleSignature(new Rectangle(36, 748, 250, 400), 1, signatureFieldName);

            IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);

            MakeSignature.SignExternalContainer(appearance, external, 8192);

            byte[] array = SHA256Managed.Create().ComputeHash(appearance.GetRangeStream());

            return Convert.ToBase64String(array);
        }
    }
}

As a result of this operation tempPdf is generated and I receive the hash for the signable bytes of the pdf document from this tempPdf file.

Then using the below code, I reopen this tempFile and embed the PKCS#7 signature which is Base64 encoded.

Code That Opens Temp Pdf And Embeds The Received Signature

public static void EmbedSignature(string tempPdf, string signedPdf, string signatureFieldName, string signature)
{
    byte[] signedBytes = Convert.FromBase64String(signature);

    using (PdfReader reader = new PdfReader(tempPdf))
    {
        using (FileStream os = File.OpenWrite(signedPdf))
        {
            IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);
            MakeSignature.SignDeferred(reader, signatureFieldName, os, external);
        }
    }
}

As a result of this operation my final signedPdf is generated. However, Adobe says that the signature is not valid due the change or corruption.

My Original File

Temporary File Generated For Signing

Final Signed File

The hash of the tempFile file that I sent to web service is:

z9qIyvtp4cRBZ1SSCQ+P0JVRinz5lvjYjXk3L7YP/IE=

The signature I received from web service is:

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

I compared the bytes of tempFile and signedFile and only the zeros of tempFile (which are used for temp signature file I think) are replaced with the actual signature in signedFile.

I am really stuck at this point. I am not sure where I should be looking next.

解决方案

In the signature you received from the web service there is:

  39   59: . . . SEQUENCE {
  41    9: . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
         : . . . . . (PKCS #7)
  52   46: . . . . [0] {
  54   44: . . . . . OCTET STRING    
         : . . . . . . 7A 39 71 49 79 76 74 70    z9qIyvtp
         : . . . . . . 34 63 52 42 5A 31 53 53    4cRBZ1SS
         : . . . . . . 43 51 2B 50 30 4A 56 52    CQ+P0JVR
         : . . . . . . 69 6E 7A 35 6C 76 6A 59    inz5lvjY
         : . . . . . . 6A 58 6B 33 4C 37 59 50    jXk3L7YP
         : . . . . . . 2F 49 45 3D                /IE=
         : . . . . . }
         : . . . . }
[...]
1955    9: . . . . . SEQUENCE {
1957    5: . . . . . . OBJECT IDENTIFIER sha1 (1 3 14 3 2 26)
         : . . . . . . . (OIW)
1964    0: . . . . . . NULL
         : . . . . . . }
1966   93: . . . . . [0] {
1968   24: . . . . . . SEQUENCE {
1970    9: . . . . . . . OBJECT IDENTIFIER contentType (1 2 840 113549 1 9 3)
         : . . . . . . . . (PKCS #9)
1981   11: . . . . . . . SET {
1983    9: . . . . . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
         : . . . . . . . . . (PKCS #7)
         : . . . . . . . . }
         : . . . . . . . }
1994   28: . . . . . . SEQUENCE {
1996    9: . . . . . . . OBJECT IDENTIFIER signingTime (1 2 840 113549 1 9 5)
         : . . . . . . . . (PKCS #9)
2007   15: . . . . . . . SET {
2009   13: . . . . . . . . UTCTime 22/09/2017 13:18:38 GMT
         : . . . . . . . . }
         : . . . . . . . }
2024   35: . . . . . . SEQUENCE {
2026    9: . . . . . . . OBJECT IDENTIFIER messageDigest (1 2 840 113549 1 9 4)
         : . . . . . . . . (PKCS #9)
2037   22: . . . . . . . SET {
2039   20: . . . . . . . . OCTET STRING    
         : . . . . . . . . . EF 37 38 3B B1 31 AB 96    .78;.1..
         : . . . . . . . . . CE FC 47 1E 32 A7 79 73    ..G.2.ys
         : . . . . . . . . . 5D 95 15 04                ]...
         : . . . . . . . . }
         : . . . . . . . }
         : . . . . . . }
2061   13: . . . . . SEQUENCE {
2063    9: . . . . . . OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
         : . . . . . . . (PKCS #1)
2074    0: . . . . . . NULL
         : . . . . . . }

Herein your base64 encoded hash appears as embedded signed data (offsets 56..99). Furthermore, the hashing algorithm is chosen as "SHA-1" (offsets 1955..1965) and the signed document hash is a 20 byte value which matches the size of SHA-1 hash values. Additionally RSA is used for signing as described in PKCS#1 1.5 (offsets 2061..2075).

Thus, it looks like your signing service does not use your input as base64 encoded pre-calculated document hash value but as plain data to sign using SHA1withRSA/2048.

So the error is not in your iText using code but in your signing service calling code.

这篇关于数字签名(PKCS#7 - 延期签名)/自应用签名后文档已被更改或损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆