如何使用iText 7和外部信任服务提供商为PDF文档加盖合格的电子印章?

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

我目前正在使用 IText7 库和外部签名服务对 pdf 文档应用合格的电子印章。但我现在在使用 iText7 PDFSigner 实际签署 pdf 时遇到问题,并且通过 PDFSigner.signDetached() 方法收到“未知 PDF 异常”。 这是我第一次使用 iText7 或实际使用数字签名,所以我不完全相信我正在以正确的方式进行操作。

为了将合格的印章应用到我的 pdf 文件,我实现了 IExternalSignature 接口,并在 Sign 方法中通过 Web 请求调用外部服务来获取签名。外部服务创建的签名是ECDSA格式签名。在请求中,我发送哈希 pdf 值、哈希签名和使用的哈希签名机制。我得到的响应是一个签名,它被转换为字节数组。

我从 IExternalSignature 实现的 Sign 方法中调用此外部服务,返回签名,但现在在尝试运行 PDFSigner.SignDetached() 方法时遇到问题,该方法会抛出“未知 PDF 异常”

这是我尝试使用收到的签名对 pdf 进行签名的代码

PdfReader pdfReader = new PdfReader(pdfFilePathLocal); //read the pdf file
            PdfSigner pdfsigner = new PdfSigner(pdfReader, new FileStream(dest, FileMode.Create), new StampingProperties());

           
            Rectangle rect = new Rectangle(36, 648, 200, 100);
            PdfSignatureAppearance appearance = pdfsigner.GetSignatureAppearance();
            appearance
                .SetReason("reason test")
                .SetLocation("location test")
                .SetPageRect(rect)
                .SetPageNumber(1);
            pdfsigner.SetFieldName("sig");
            

            IExternalSignature serverSignature = new ServerSignature(certificateAuthLocal, AuthenticationCertificatePrivateKey);


            IX509Certificate[] certificateWrappers = new IX509Certificate[chain.Length];

            for (int i = 0; i < certificateWrappers.Length; ++i)
            {
                certificateWrappers[i] = new X509CertificateBC(chain[i]);
            }

            pdfsigner.SignDetached(serverSignature, certificateWrappers, null, null, null, 0, PdfSigner.CryptoStandard.CMS);

任何帮助将不胜感激,因为我没有使用 iText7 或将数字签名应用于 PDF 文件的经验。甚至不确定这是否是正确的方法。

c# cryptography digital-signature itext7
1个回答
0
投票

我设法使用返回的签名对 PDF 文件进行签名,问题是证书未加载。但是当我通过 acrobat reader 打开文件并验证签名时,签名无效,签名中包含格式或信息错误

签名 PDF 文件的链接:签名 pdf

我的 IExternalSignature 实现中的代码:

在 Sign() 方法中,我使用 SHA256 对消息进行哈希处理:

public byte[] Sign(byte[] message)
    {
        
        try
        {
            //hash the message digest
            var hashAlgo = new Sha256Digest();
            hashAlgo.BlockUpdate(message, 0, message.Length);
            byte[] hashToSign = new byte[hashAlgo.GetDigestSize()];
            hashAlgo.DoFinal(hashToSign, 0);

            //return the signature
            signatureLocal = this.SendRequest(hashToSign);
            return signatureLocal;
        }
        catch (Exception)
        {

            throw;
        }
    }

然后调用签名服务:

private byte[] SendRequest(byte[] message)
    {
        var signatureRequest = new SignatureRequest();
        var baseUrl = "https://hs-abnahme.a-trust.at/SealQualified/v1";

        baseUrl = baseUrl.TrimEnd('/');
        
        var sid = "dummy";

        signatureRequest.AuthSerial = authenticationCertificate.SerialNumber.ToString(10);
        signatureRequest.Hash = Convert.ToBase64String(message);
        signatureRequest.HashSignature = Convert.ToBase64String(this.SignMessageDigest(message));
        signatureRequest.HashSignatureMechanism = HashSignatureMechanism;

        //request json body
        var reqStr = JsonSerializer.Serialize(signatureRequest);

        string url = $"{baseUrl}/Sign/{HttpUtility.UrlEncode(sid)}";

        if (!this.PostRequest(url, reqStr, out string ResponseData))
        {
            return null;
        }

        var respObj = JsonSerializer.Deserialize<SignatureResponse>(ResponseData);
        if (null != respObj)
        {
            return Convert.FromBase64String(respObj.Signature);
        }

        return null;
    }

此外,哈希值已签名:

 private byte[] SignMessageDigest(byte[] message)
    {
        //Generate the signature of the pdf hash data with the private key
        ISigner signer = Org.BouncyCastle.Security.SignerUtilities.GetSigner(HashSignatureMechanism);
        signer.Init(true, privateKey);
        signer.BlockUpdate(message, 0, message.Length);
        var hashSignature = signer.GenerateSignature();


        return hashSignature;
    }

请求被发送到外部服务,外部服务返回签名。这适用于PDF文件,但是当打开PDF文件时,它无效。我在这里还缺少什么?

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