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

.NET使用智能卡证书实现XAdES签名时抛出CryptographicException

使用智能卡证书进行XAdES签名时出现参数解析错误

我尝试用智能卡中存储的证书对XML文档进行XAdES签名,使用智能卡配套软件签名同一份XML可以正常完成,但自行编写的代码在执行AddSignatureToDocument方法中的_xadesSignedXml.ComputeSignature()时,系统弹出智能卡PIN输入框,输入PIN后抛出CryptographicException,错误HRESULT为-2146435068(0x80100004),提示“一个或多个提供的参数无法正确解析”。

代码实现

public class XadesWrapper
{
    private X509Certificate2 _certificate;
    private X509Chain _chain;
    private XmlDocument _envelopedSignatureXmlDocument;
    private XadesSignedXml _xadesSignedXml;
    private int _docDataObjectCounter;
    public byte[] _signedDoc;

    public XadesWrapper(XmlDocument xmlDoc, X509Certificate2 xCert)
    {
        try
        {
            _envelopedSignatureXmlDocument = xmlDoc;
            _certificate = xCert;   // 从智能卡导入的证书
            AddReference();
            CheckCertificate();
            AddKeyInfo();
            AddObjectInfo();
            AddSignatureToDocument();
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    private void AddReference()
    {
        Reference reference = new Reference();
        _docDataObjectCounter = 1;

        _xadesSignedXml = new XadesSignedXml(_envelopedSignatureXmlDocument);
        _xadesSignedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";

        reference.Id = "r-id-" + _docDataObjectCounter;
        reference.Uri = "";
        reference.Type = "";
        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());

        _xadesSignedXml.AddReference(reference);
    }

    private void CheckCertificate()
    {
        if (_certificate == null)
            return;

        _chain = new X509Chain();
        _chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
        _chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
        _chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30);
        _chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
        if (_chain.Build(_certificate) == true)
            AddKeyInfo();
        else
        {
            _certificate = null;
            _chain = null;
            throw new ArgumentException("证书链无效。");
        }
    }

    private void AddKeyInfo()
    {
        RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)_certificate.PrivateKey;
        _xadesSignedXml.SigningKey = rsaKey;

        KeyInfo keyInfo = new KeyInfo();
        keyInfo.AddClause(new KeyInfoX509Data(_certificate));
        keyInfo.AddClause(new RSAKeyValue(rsaKey));

        this._xadesSignedXml.KeyInfo = keyInfo;
    }

    private void AddObjectInfo()
    {
        _xadesSignedXml.Signature.Id = "id-" + _certificate.Thumbprint.ToLower();

        XadesObject xadesObject = new XadesObject();
        xadesObject.QualifyingProperties.Target = "#" + _xadesSignedXml.Signature.Id;
        xadesObject.QualifyingProperties.SignedProperties.Id = "xades-" + _xadesSignedXml.Signature.Id;

        Cert cert = new Cert();
        cert.IssuerSerial.X509IssuerName = this._certificate.IssuerName.Name;
        cert.IssuerSerial.X509SerialNumber = BigInteger.Parse(this._certificate.SerialNumber, NumberStyles.HexNumber).ToString();
        cert.CertDigest.DigestMethod.Algorithm = "http://www.w3.org/2001/04/xmlenc#sha256";
        cert.CertDigest.DigestValue = new SHA256CryptoServiceProvider().ComputeHash(_certificate.RawData);

        xadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningCertificate.CertCollection.Add(cert);
        xadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningTime = DateTime.Now;

        DataObjectFormat newDataObjectFormat = new DataObjectFormat();
        newDataObjectFormat.Description = "";
        newDataObjectFormat.MimeType = "text/xml";
        newDataObjectFormat.ObjectReferenceAttribute = "#r-id-" + _docDataObjectCounter;
        xadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection.Add(newDataObjectFormat);

        _xadesSignedXml.AddXadesObject(xadesObject);
    }

    private void AddSignatureToDocument()
    {
        _xadesSignedXml.ComputeSignature();
        _xadesSignedXml.SignatureValueId = "value-" + _xadesSignedXml.Signature.Id;

        _envelopedSignatureXmlDocument.DocumentElement.AppendChild(_envelopedSignatureXmlDocument.ImportNode(_xadesSignedXml.GetXml(), true));

        _signedDoc = Encoding.UTF8.GetBytes(_envelopedSignatureXmlDocument.OuterXml);
    }
}

调用栈信息

at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)
   at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
   at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
   at System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash)
   at System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)
   at Microsoft.Xades.XadesSignedXml.ComputeSignature()

内容的提问来源于stack exchange,提问作者Jan J.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:28:20