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

如何在C#中使用USB令牌对XML文件进行签名?

使用USB令牌对XML文档进行数字签名

USB令牌中的数字证书(带不可导出私钥)可通过系统证书存储或PKCS#11接口访问,结合.NET的System.Security.Cryptography.Xml类即可完成XML签名,以下是具体实现步骤:

1. 从USB令牌中获取签名证书

USB令牌会被系统识别为证书存储的一部分,可通过X509Store读取目标证书:

using System.Security.Cryptography.X509Certificates;

// 打开当前用户的个人证书存储
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

// 按证书主体名称筛选(也可按Thumbprint等字段定位)
var targetCerts = store.Certificates.Find(
    X509FindType.FindBySubjectName, "你的证书主体名称", validOnly: true);

if (targetCerts.Count == 0)
    throw new InvalidOperationException("未找到USB令牌中的目标签名证书");

var signingCert = targetCerts[0];
// 确认证书带有私钥(USB令牌的私钥不可导出,仅能在令牌内使用)
if (!signingCert.HasPrivateKey)
    throw new InvalidOperationException("选中的证书无可用私钥");

2. 用证书私钥签署XML文档

基于标准XML签名流程,替换签名密钥为USB令牌证书的私钥即可,系统会自动触发令牌的PIN验证(若设置):

using System.Xml;
using System.Security.Cryptography.Xml;

// 加载待签名的XML文档
var xmlDoc = new XmlDocument { PreserveWhitespace = true };
xmlDoc.Load("input.xml");

// 初始化SignedXml并绑定签名密钥
var signedXml = new SignedXml(xmlDoc) { SigningKey = signingCert.PrivateKey };

// 添加签名引用(此处为签名整个文档)
var reference = new Reference { Uri = "" };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
signedXml.AddReference(reference);

// 添加密钥信息,将证书嵌入签名以便验证方获取
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(signingCert));
signedXml.KeyInfo = keyInfo;

// 计算并插入签名
signedXml.ComputeSignature();
var signatureElement = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(signatureElement, true));

// 保存签名后的XML
xmlDoc.Save("signed_output.xml");

3. 特殊场景处理(PKCS#11接口令牌)

若USB令牌仅支持PKCS#11接口,需使用第三方库(如Pkcs11Interop)来访问令牌内的私钥,核心逻辑是通过PKCS#11会话获取签名密钥,再替换上述代码中的signingCert.PrivateKey部分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 06:06:26