当前位置: 首页 > 知识库问答 >
问题:

使用itextsharp 5.5.13.2和SHA-256对PDF签名时的“错误未指定算法”

百里杰
2023-03-14

早上好,我正在尝试使用ItextSharp 5.5.13.2和SHA-256对PDF文档进行签名,但签名时出现错误“指定的算法无效”。使用SHA-1时,不会发生此错误。NetFramework 4.7.2要签署PDF,下一个方法是我用来签署PDF的方法。

    public void SignPDF(string PathSourceDoc, string PathTargetDoc, X509Certificate2 certificate, string pathLogo)
    {
        using (PdfReader reader = new PdfReader(PathSourceDoc))
        using (var writer = new FileStream(PathTargetDoc, FileMode.Create, FileAccess.Write))
        using (var stamper = PdfStamper.CreateSignature(reader, writer, '\0', null, true))
        {


            var signature = stamper.SignatureAppearance;
            signature.CertificationLevel = PdfSignatureAppearance.NOT_CERTIFIED;
            signature.Reason = "My Reason";
            signature.Location = "My Location";
            signature.SignDate = DateTime.Now;
            signature.Acro6Layers = true;

            PdfSignature objSignature = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1);
            objSignature.Date = new PdfDate(signature.SignDate);
            signature.CryptoDictionary = objSignature;

            var bcCert = DotNetUtilities.FromX509Certificate(certificate);
            string name = CertificateInfo.GetSubjectFields(bcCert).GetField("CN");
            string industry = CertificateInfo.GetSubjectFields(bcCert).GetField("O");
            string position = CertificateInfo.GetSubjectFields(bcCert).GetField("T");
            DateTime date = DateTime.Now;

            signature.Layer2Text = "Digital Signed by: " + name + "\n" +
                                   "Reason: " + "My Reason" + "\n" +
                                   "Date: " + date;
            signature.Layer2Font = new Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 8);

            Image img = Image.GetInstance(pathLogo);
            signature.SignatureGraphic = img;

            signature.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
            Rectangle rect = new Rectangle(50, 50, 300, 110);
            signature.SetVisibleSignature(rect, 1, null);
            var standard = CryptoStandard.CADES;

            /*I tried this way but I get an error of type Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The requested operation is not supported.'*/
            X509Certificate cert = certificate;
            X509Certificate2 signatureCert = new X509Certificate2(cert);
            var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(signatureCert.PrivateKey).Private;// the error is generated in this line (Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The requested operation is not supported.').
            IExternalSignature es = new PrivateKeySignature(pk, "SHA-256");
            /****************************************************************************************************************************************************************/

            X509Certificate2Signature externalSignature = new X509Certificate2Signature(certificate, DigestAlgorithms.SHA1); /*throws an exception on this line of type "System.ArgumentException: 'Unknown encryption algorithm System.Security.Cryptography.RSACng'" 
                                                                                                                              * when using .NET Core 3.1. this always happens, it doesn't matter if I use sha1 or use any other algorithm, it always generates error*/


            MakeSignature.SignDetached(signature, externalSignature, new[] { bcCert }, null, null, null, 0, standard);
        }
    }

该方法接收我需要签名的PDF路径、签名时将创建的PDF路径、证书以及用于在签名中显示图像的徽标路径作为输入参数。事实上,我不知道我做错了什么,因为我一直在研究相关的问题,它应该与SHA-1和SHA-256和。NetFramework。

然后我将项目迁移到了。NetCore 3.1试图解决这个问题,但我得到了一个新的错误(代码中有注释)。我的目标是使用。NetCore和允许我使用sha256签署pdf。为了使程序正常工作,我修改SignPdf方法没有问题。感谢您的任何贡献或信息链接。谢谢你的帮助。

Psdt:这是堆栈跟踪,如下所示。。。

共有1个答案

冯野
2023-03-14

显然,X509Certificate2Signature使用的Microsoft加密API不支持SHA-256。

您可以使用X509证书2签名实例作为MakeSignature的参数。签名分离。

如果您的X509Certificate2PrivateKeyRSACryptServiceProvider(您的证书似乎就是这样),X509Certificate2Signature。在通话中签名

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PrivateKey;
return rsa.SignData(message, hashAlgorithm);

rsacyptoserviceprovider。SignData起初显然支持“SHA256”,因为在将执行转发到SignHash之前,它必须计算出要签名的哈希值。

rsacyptoserviceprovider。但是,根据Microsoft文档中关于该方法的描述,SignHash不支持SHA-256:

此方法创建使用VerifyHash方法验证的数字签名。

有效的哈希算法是SHA1和MD5。算法标识符可以通过使用MapNameToOID方法从哈希名称派生。

由于SHA1和MD5存在冲突问题,Microsoft建议使用基于SHA256或更高版本的安全模型。

(查阅时间:2021-06-2411:07)

因此,您会得到“指定的算法无效”错误。

因此,本质上,不应该再将RSA签名的IExternalSignature实现基于RSACryptServiceProvider

也许这就是为什么未将X509Certificate2Signature移植到iText版本7的原因。。。

另一种方法可能是首先检查Private ateKey是否是RSACng,在这种情况下将其用作RSACng。RSA算法的这种下一代密码学(CNG)实现应该支持更好的哈希算法...

 类似资料:
  • 编辑:问题是我使用十六进制编码的字符串作为键,我应该使用原始字节。如何从openssl命令中获取原始字节? ---原问题--- 我正在尝试按照以下说明创建签名iam请求:https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html. 它基本上是说要产生签名密钥和签名,您需要遵循以下步骤: 我创建了以下外壳脚

  • 我想分两步使用RSA/PSS签名制作SHA256,首先散列一条消息,然后使用RSASSA-PSS签名摘要 但我使用SHA256时RSA/PSS无法验证 我需要一些帮助,谢谢你的帮助。

  • 首先,我对加密/签名还是新手,所以请容忍任何滥用术语的行为。 我需要在C#中创建一个签名,该签名将被Python库验证。在Python中,解码/验证签名只需一段简单的代码: 我当前的C#代码如下所示: 但是,签名在Python代码中未通过验证检查。它看起来像PSS填充。Net库默认使用MGF1。然而,我相信我有问题,因为掩码生成函数(MGF1)在Python代码中使用256位哈希,但在C#中默认为

  • 我遇到了具有的阻止程序。NET Framework 4.5版用于使用数字签名对XML进行签名。 我的问题是,需要使用RSA SHA-256算法使用X.509证书对单个XML元素进行签名。我读过很多书。NET就这个主题发表了文章,似乎有一个最初在CLR安全项目RSAPKCS1SHA256SignatureDescription中开发的解决方案。cs类。RSAPKCS1SHA256SignatureD

  • 我正在尝试使用远程web服务来演唱pdf,该服务返回一个XML签名,该签名由签名和最终用户证书组成。 我需要使用此签名通过IText签名对pdf进行签名,因为web服务。 所有IText示例都使用消息格式,但我不确定应该如何处理XML签名。 打开临时Pdf并嵌入接收到的签名的代码 从web服务返回的XML签名: 当我将返回的签名与上面的代码一起使用时,签名验证失败,出现“错误遇到时BER解码”。

  • 我正在尝试用Itext 5和BouncyCastle 1.48验证PDF签名。我的代码适用于许多已签名的pdf,但也适用于特定客户的某些pdf。这是我的Java代码 有时我会遇到这样的例外: JAVAlang.IllegalArgumentException:getInstance:org中的未知对象。蹦蹦跳跳。asn1。Asn1在组织中列举。蹦蹦跳跳。asn1。ASN1序列。组织上的getIns