在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,它为false。我的(基本)理解是,我不应该拥有私钥,并且应该能够使用公钥创建签名。
我错过什么?
提前致谢