iText7 版本 8.0.2 和 dotnet 6 - 签名的 pdf 文档显示“自应用签名以来,文档已被更改或损坏”

问题描述 投票:0回答:1

我真的需要帮助,请。

我在 Stackoverflow 上检查了其他类似的问题,但它不适用于我的情况。

情况:我正在开发一个应用程序,需要使用 USB 令牌对 PDF 文档进行签名。

生成的pdf带有数字签名,但验证失败。

Adobe verification result

我按照以下步骤操作:

  1. 我在X509Store中选择证书
  2. 我使用 ContentInfo、SignedCms 和 CmsSigner 完成整个签名过程。这将打开模式,以便我可以输入 PIN 码。
  3. 我使用外部容器对 pdf 进行签名并生成签名的 pdf。
X509Store st = new X509Store(StoreName.My, StoreLocation.LocalMachine);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certSelected = st.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
st.Close();

var cert = certSelected[0];

using var reader = new PdfReader(pdfPathSelected);
{
    using (var outputStream = new MemoryStream())
    {
        var signer = new PdfSigner(reader, outputStream, new StampingProperties());

        var appearance = new SignatureFieldAppearance(string.Empty);

        var signerName = _x509CertificateService.GetSignerName(chain[0]);

        var appearanceText = new SignedAppearanceText();
        appearanceText.SetSignedBy(signerName)
                      .SetReasonLine("Reason: Assinatura Digital.")
                      .SetLocationLine("Location: Sistema Doc Digital.")
                      .SetSignDate(signer.GetSignDate())
                      .GenerateDescriptionText();


        var fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Images", "tcpdf_signature.png");

        var img = ImageDataFactory.Create(fileName);

        appearance.SetContent(appearanceText, img);

        signer.SetSignatureAppearance(appearance);
        signer.SetPageNumber(signer.GetDocument().GetNumberOfPages());
        signer.SetPageRect(signaturesCount > 0 ? new Rectangle(50, 50, 450, 30) : new Rectangle(50, 5, 450, 30));

   
        var contentInfo = new ContentInfo(File.ReadAllBytes(pdfPathSelected));

        var signedCms = new SignedCms(contentInfo, true);

        var rsaCng = cert.GetRSAPrivateKey() as RSACng;

        var cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert, rsaCng)
        {
            DigestAlgorithm = new Oid("SHA256"), // SHA256
            IncludeOption = X509IncludeOption.EndCertOnly
        };

        signedCms.ComputeSignature(cmsSigner, false);

        var externalSignature = new CmsSignatureContainer(signedCms);
        signer.SignExternalContainer(externalSignature, 8192);

        File.WriteAllBytes(destPdfSigned, outputStream.ToArray());

    }
}

CmsSignatureContainer 类:

public class CmsSignatureContainer : IExternalSignatureContainer
{
    private readonly SignedCms signedCms;

    public CmsSignatureContainer(SignedCms signedCms)
    {
        this.signedCms = signedCms;
    }

    public byte[] Sign(Stream data)
    {
        // You may need to adjust the format depending on the specific requirements of your PDF signature
        return signedCms.Encode();
    }

    public void ModifySigningDictionary(PdfDictionary signDic)
    {
        signDic.Put(PdfName.Filter, PdfName.Adobe_PPKLite);
        signDic.Put(PdfName.SubFilter, PdfName.Adbe_pkcs7_detached);
    }
}
.net-6.0 digital-signature itext7 corrupt rsa-sha256
1个回答
0
投票

我成功解决了问题,签名实现不正确,外部签名容器的使用也不正确。 正确的做法是创建一个继承自 IExternalSignature 的类,并在 Sign 方法的实现中创建一个 SHA256 哈希器,计算哈希值并在 RSA 验证密钥上生成签名哈希值。 谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.