X509证书和XmlDsig
我需要在 C# (4.0) 中使用 X509Certificate(应验证签名的文件提供的 .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 属性,它是错误的。 我的(基本)理解是我不应该拥有私钥,我应该能够使用公钥创建签名。
我缺少什么?
提前致谢
I need, in C# (4.0), to sign an XML (XMLDSig Envelope) using a X509Certificate (a .p7b file provided by the one which should verify the signature)
I do not have experience in security, my knowledge stops to some basic concepts about cryptography .
Here is what i have done:
1) I have installed the certificate in: Certificates - Current User - Trusted Root Certification.
2) from .net i succesfully loaded the certificate with this code:
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) I tried to use the public key of the certificate to create a signature with the following code;
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));
but when computing the signature i get an exception: "Object contains only the public half of a key pair. A private key must also be provided."
I checked the property HasPrivateKey in the certificate and it is false.
My (basic) understanding is that I should not have the private key and I should be able to create a signature using the public key.
What I'm missing ?
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
.p7b 代表 PKCS#7 格式,通常不包含私钥。当您签署文档时,您可以通过应用私钥来证明其真实性,该私钥属于您并且必须保密。因此,任何人(可能除了您的网络管理员或有时是银行)都不太可能向您提供您的私钥。
.p7b stands for PKCS#7 format which doesn't normally contain a private key. When you sign the document, you prove it's authenticity by applying a private key, which belongs to you and which you must keep secret. So it's very unlikely that anyone (besides probably your network administrator or sometimes a bank) would give you your private key.
如果您要为您的内容创建数字签名,您将使用您的私钥加密该内容的摘要,并将您的原始内容+您的签名发送给接收者。
验证阶段:
验证者将使用您的公钥解密您的签名,并获得哈希值 H1。然后原始内容被接收者散列到H1。
接收者验证H1是否等于H2,如果不等于则签名验证失败。
If you were to create a digital signature for your content, your will encrypt the digest of this content with your Private Key and send your orignal content + your signature to the recepient.
Verification phase:
The verifier, will decrypt your signature using your public key, and get hash H1. Then the orignal content is hashed by recepient to H1.
Recepient verifies if H1 equals to H2, if not signature verification fails.