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
.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.