Search code examples
c#x509certificate2

Performing a digital signature using X509Certificate2 prompt for a password to use private key


How can i make sure the C# code uses a password to use the certificate's private key? The certificate is installed in the CurrentUser/Personal store. I tried but still my code uses the private key without prompting for a password.

enter image description here

byte[] fileData = File.ReadAllBytes(path);
ContentInfo contentInfo = new ContentInfo(fileData);

SignedCms signedCms = 
new SignedCms(SubjectIdentifierType.SubjectKeyIdentifier, contentInfo, true);
CmsSigner signer = 
new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, MyLoadedCert);
signer.IncludeOption = X509IncludeOption.WholeChain;
signedCms.ComputeSignature(signer); // Works fine without prompting password

byte[] encoded = signedCms.Encode();
File.WriteAllBytes(signatureFilePath, encoded);

Solution

  • When I ran you code with strong key protection enabled I've got an exception Provider could not perform the action since the context was acquired as silent.. This was because I did not specify the silent parameter in ComputeSignature method and by default it is set to true (so it seems).

    When you change this line of code

    signedCms.ComputeSignature(signer);
    

    to

    signedCms.ComputeSignature(signer, false);
    

    then it will prompt for user interaction when necessary i.e. when you have specified strong key protection in Certificate Import Wizard. The documentation can be found here.

    The default action/level of strong private key protection is medium meaning that user will have to approve (click OK) the use of private key. You can change it to High protection and set set the password if you want (see screens below).

    After strong private key protection checkbox is set

    Choose level of protection

    Selected High level of protection