X509证书和XmlDsig


春风助手
2025-02-04 09:32:34 (21天前)

在C#(4.0)中,我需要使用X509Certificate(应该验证签名的人提供的.p7b文件)对XML(XMLDSig信封)进行签名。我没有安全经验,我的知识仅限于一些基本概念关于密码学。

这是我所做的:

1)我已将证书安装在:证书-当前用户-可信根证书中。

2)从.net我成功用以下代码加载证书:


  1. X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
    try
    {
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, certName, false);
    if (certs.Count == 0)
    return null;

    return certs[0];
    }
    finally
    {
    store.Close();
    }

3)我尝试使用证书的公钥通过以下代码创建签名;


  1. XmlDocument doc = new XmlDocument();
    doc.PreserveWhitespace = true;
    var reader = new StringReader(xml);
    doc.Load(reader);
    var signedXml = new SignedXml(doc);
    X509Certificate2 certificate = this.GetCertificateFromStore(certName); // the previous code
    signedXml.SigningKey = (RSACryptoServiceProvider)certificate.PublicKey.Key;
    var reference = new Reference();
    reference.Uri = “”;
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);
    signedXml.AddReference(reference);
    signedXml.ComputeSignature(); // exception!!!
    var element = signedXml.GetXml();
    doc.AppendChild(doc.ImportNode(element, true));

但是当计算签名时,我得到一个例外:“对象仅包含密钥对的公共一半。还必须提供私有密钥。”

我检查了证书中的属性HasPrivateKey,它为false。我的(基本)理解是,我不应该拥有私钥,并且应该能够使用公钥创建签名。

我错过什么?

提前致谢

2 条回复
  1. 1# 春风助手 | 2020-08-05 18-04

    p7b代表PKCS#7格式,通常不包含私钥。在文档上签名时,您可以通过应用属于您并且必须保密的私钥来证明其真实性。因此,几乎没有任何人(可能是您的网络管理员,有时是银行)会给您您的私钥。

登录 后才能参与评论