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

使用埃及ETA证书签名抛出CryptographicException:密钥不存在

问题根因

执行CMS签名抛出key does not exist异常的核心原因是代码中加载的preprod-root-ca.crt是仅包含公钥的根CA证书,没有签名必需的私钥:

  • 数字签名的核心逻辑是用签名方的私钥对内容摘要做加密运算,仅持有公钥无法完成签名操作
  • 根CA证书的作用是校验证书链信任关系,本身不具备签名权限,不能直接用于签名
  • 原代码中调用GetRSAPublicKey仅提取了公钥对象,没有绑定可用的私钥资源,CmsSigner初始化后没有可用签名密钥,执行ComputeSignature必然报错
排查步骤
  • 先确认证书格式:CRT/CER后缀的证书文件默认只存储公钥,无法用于签名;可用于签名的证书必须是包含私钥的PFX/P12格式文件,由埃及ETA签发给对应纳税主体
  • 加载证书后先校验私钥属性:证书加载完成后立刻检查HasPrivateKey属性,为false则直接定位为证书文件错误
  • 权限校验:如果证书导入到Windows系统证书存储使用,要确认程序运行身份对私钥容器有读取权限,权限不足也会抛出同类异常
修复方案
  1. 替换证书文件:将代码中加载的根CA证书替换为ETA签发的、包含你方主体私钥的PFX格式签名证书
  2. 修正证书加载逻辑,加载PFX时传入私钥密码并设置正确的密钥存储标记,参考代码如下:
Dim textToSign As String = vstrToHash
Dim contentInfo As New ContentInfo(Encoding.UTF8.GetBytes(textToSign))
Dim signedCms As New SignedCms(contentInfo, False)
' 替换为实际的PFX证书路径、私钥密码
Dim signCert As New X509Certificate2(
    "d:\eta-sign-cert.pfx", 
    "your-pfx-private-password",
    X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet
)
' 提前校验私钥存在性
If Not signCert.HasPrivateKey Then
    Throw New InvalidOperationException("当前加载的证书不包含私钥,无法完成签名")
End If
Dim Signer As CmsSigner = New CmsSigner(signCert)
' 显式指定SHA256摘要算法,匹配ETA接口签名要求
Signer.DigestAlgorithm = New Oid("2.16.840.1.101.3.4.2.1")
signedCms.ComputeSignature(Signer, False)
  1. 按ETA接口要求调整签名参数:如果接口要求附带完整证书链,将ComputeSignature的第二个参数改为true即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:18:33