Search code examples
c#encryptionx509certificatex509certificate2pfx

How can I encrypt, decrypt and sign using .pfx certificate?


I have a .pfx certificate file on my computer. I want to to encrypt a message with its public key, and then decrypt it with the private.

Also I want to sign another message with its private key, and then check the signature. And I need to get the information about the sertificate the message was signed with from that message.

How can I do it using System.Security.Cryptography?


Solution

  • You can open the PFX in .NET, like the following:

    var path = <YOUR PFX FILE PATH>;
    var password = <YOUR PASSWORD>;
    
    var collection = new X509Certificate2Collection();
    
    collection.Import(path, password, X509KeyStorageFlags.PersistKeySet);
    

    Then, enumerate over the X509Certificate2Collection. Once you have a certificate (assuming there is a single certificate), then:

    var certificate = collection[0];
    

    To encrypt data, you can use:

    var publicKey = certificate.PublicKey.Key as RSACryptoServiceProvider;
    
    var encryptedData = publicKey.Encrypt(<yourdata>, false);
    

    Here, i didn't use OAEP for encryption, but you can use it by setting the fOAEP to true for the second parameter.

    To decrypt data, you can use:

    var privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
    
    var data = privateKey.Decrypt(encryptedData, false);
    

    A certificate in the PFX may not have a corresponding private key, so you can use the following property to check if the private key exists before accessing the PrivateKey property

    if (!certificate.HasPrivateKey)
        throw new Exception("The certificate does not have a private key");
    

    If you have encrypted with OAEP, then you have to decrypt with fOAEP set to true.

    To sign data, you can use:

    var signature = privateKey.SignData(<yourdata>, "SHA1");
    

    To verify the signature, you can use:

    var isValid = publicKey.VerifyData(<yourdata>, "SHA1", signature);
    

    Here i used SHA1 which is not considered strong. You can use other hashing algorithms like SHA256 which are stronger.

    Finally, if you're message is a small string, then the previous procedure is fine. However, if you're encrypting large data, then i suggest that you use symmetric encryption and then encrypt the symmetric key with the public key. (See X509Certificate2 Class for full example.)