X509Certificate和XmlDsig

时间:2011-04-26 17:27:49

标签: c# x509certificate signature xml-signature

我需要在C#(4.0)中使用X509Certificate(由应该验证签名的.p7b文件提供的.p7b文件)签署XML(XMLDSig Envelope) 我没有安全方面的经验,我的知识停留在一些关于密码学的基本概念上。

这就是我所做的:

1)我已将证书安装在:证书 - 当前用户 - 受信任的根证书。

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

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)我尝试使用证书的公钥来创建一个包含以下代码的签名;

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,它是错误的。 我的(基本)理解是我不应该拥有私钥,我应该能够使用公钥创建签名。

我缺少什么?

提前致谢

2 个答案:

答案 0 :(得分:2)

.p7b代表PKCS#7格式,通常不包含私钥。当您签署文档时,您通过应用属于您的私钥来证明其真实性,您必须保密。因此,任何人(除了可能是您的网络管理员或有时是银行)都不太可能为您提供您的私钥。

答案 1 :(得分:2)

如果您要为自己的内容创建数字签名,您将使用私钥加密此内容的摘要,并将您的原始内容+您的签名发送给收件人。

验证阶段: 验证程序将使用您的公钥解密您的签名,并获取哈希H1。然后通过接收到H1来对原始内容进行散列。 如果签名验证失败,Recepient将验证H1是否等于H2。