I want to create a web application, where the server creates a pdf document, and then the user signs it with some personal digital certificate, (eID, Id card, nif, etc.)
Problem is, when I try it localy (Debug) it works, because I have the certificate installed in the local machine, but when I publish, the private key of the certificate is not in the certificate, and so, I can not sign the pdf.
public ActionResult Index()
{
HttpClientCertificate cert = Request.ClientCertificate;
X509Certificate2 x509cert2 = new X509Certificate2(cert.Certificate);
}
In Debug, so, in local machine x509cert2.PrivateKey is not null, but if I publish, x509cert2.PrivateKey is null, so, when I try:
byte[] contentPdfUnsigned = System.IO.File.ReadAllBytes(path + name + ".pdf");
ContentInfo objContent = new ContentInfo(contentPdfUnsigned);
SignedCms objSignedData = new SignedCms(objContent);
CmsSigner objSigner = new CmsSigner(x509cert2);
objSignedData.ComputeSignature(objSigner, false);
byte[] bytSigned = objSignedData.Encode();
In the line "objSignedData.ComputeSignature(objSigner, false);" throws a exception:
System.Security.Cryptography.CryptographicException: Key does not exist.
Is there some method to make the user to pass me the private key?
When executed localy x509cert2.PrivateKey.ToXMLString(true);
prompts this message:
in english:
Is there a way to prompt this message (or another) to allow the user to pass the private key?
In most cases there's no way the user can or should pass you the private key - this is both technically impossible and would break the idea of the private key (passing it to you makes its privacy void). You need to either create a client-side module to do actual signing, or use some pre-created module. In this answer I describe the solution that we offer, and you can create your own client-side module as well.