You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用智能卡与iTextSharp签署PDF遇RSACng算法异常问题排查

问题分析

异常System.ArgumentException: Unknown encryption algorithm System.Security.Cryptography.RSACng的核心原因是你用的旧版iTextSharp(5.x系列)的X509Certificate2Signature类只支持传统的RSACryptoServiceProvider,不兼容.NET引入的RSACng加密提供者。Bit4id TokenMe Evo智能卡的私钥是通过RSACng暴露的,而你的USB Token用的是旧的RSACryptoServiceProvider,所以前者触发异常,后者正常。

另外,无PIN输入提示是因为代码在初始化签名器时就报错中断了,根本没走到需要访问私钥、触发PIN验证的环节。

解决方案

你需要自定义一个支持RSACng的IExternalSignature实现,替代原生的X509Certificate2Signature,具体步骤如下:

1. 自定义RSACng签名类

添加一个实现IExternalSignature的类,直接调用RSACng的签名方法,自动触发智能卡的PIN输入框:

using iTextSharp.text.pdf.security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

public class RSACngSignature : IExternalSignature
{
    private readonly X509Certificate2 _certificate;
    private readonly string _hashAlgorithm;

    public RSACngSignature(X509Certificate2 certificate, string hashAlgorithm)
    {
        _certificate = certificate ?? throw new ArgumentNullException(nameof(certificate));
        _hashAlgorithm = hashAlgorithm ?? throw new ArgumentNullException(nameof(hashAlgorithm));
    }

    public string GetHashAlgorithm()
    {
        return _hashAlgorithm;
    }

    public string GetEncryptionAlgorithm()
    {
        return "RSA";
    }

    public byte[] Sign(byte[] message)
    {
        using var rsa = _certificate.GetRSAPrivateKey() as RSA;
        if (rsa == null)
        {
            throw new InvalidOperationException("证书无RSA私钥");
        }
        // 调用RSACng签名方法,自动触发智能卡PIN验证
        return rsa.SignData(message, new HashAlgorithmName(_hashAlgorithm), RSASignaturePadding.Pkcs1);
    }
}

2. 替换签名代码中的X509Certificate2Signature

在signPdf方法中,把原来的:

IExternalSignature externalSignature = new X509Certificate2Signature(certificate, "SHA-1");

替换为:

// 建议改用SHA-256,SHA-1已被列为不安全算法
IExternalSignature externalSignature = new RSACngSignature(certificate, "SHA-256");

3. 额外优化建议

  • 替换SHA-1为SHA-256:SHA-1已被密码学界认定不安全,主流PDF阅读器可能会标记SHA-1签名为不可信,建议全程使用SHA-256及以上哈希算法。
  • 检查证书私钥权限:确保WinForm应用有访问智能卡私钥的权限,部分智能卡驱动需要应用以管理员权限运行(调试时可右键以管理员身份启动测试)。
  • 考虑升级到iText 7:iTextSharp是iText的旧版.NET分支,现已停止维护,iText 7对.NET新加密API(包括RSACng)有原生支持,能避免这类兼容性问题,同时提供更完善的PDF签名功能。
验证修改后的流程

修改后,当代码执行到SignDetached时,会调用自定义RSACngSignature的Sign方法,此时访问智能卡私钥会触发PIN输入框,输入正确PIN后即可完成PDF签名。

内容的提问来源于stack exchange,提问作者user2905416

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:19:56