2

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

这是我所做的:

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

我错过了什么?

提前致谢

4

2 回答 2

2

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

于 2011-04-26T17:44:37.490 回答
2

如果您要为您的内容创建数字签名,您将使用您的私钥对该内容的摘要进行加密,并将您的原始内容和您的签名发送给接收者。

验证阶段:验证者将使用您的公钥解密您的签名,并获得哈希 H1。然后原始内容由接收者散列到 H1。接收方验证 H1 是否等于 H2,否则签名验证失败。

于 2011-05-06T20:43:47.457 回答