Search code examples
c#.netwindows-server-2012x509certificate2chilkat

Loading X509Certificate2 ends with An internal error occurred on Windows server 2012


I`m trying to load certificate from path and getting internal server error on windows server. While I do it on windows 10 everything works fine.

Not working console application Code

var path = args[0];
var password = args[1];
var certificate2 = new X509Certificate2(path, password);

But getting error

Unhandled exception. Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: An internal error occurred.
   at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
   at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
   at CertCoreTest.Program.Main(String[] args) in C:\Users\Admin\Documents\Visual Studio 2019\Projects\CertTest\CertCoreTest\Program.cs:line 12

Hack working code (not sure why it works)

var path = args[0];
var password = args[1];

Chilkat.Cert cert = new Chilkat.Cert();
var success = cert.LoadPfxData(File.ReadAllBytes(path), password);
if (success == false)
{
    throw new Exception(cert.LastErrorText);
}

var bytes = cert.ExportToPfxData(password, true);
var ceeert = new X509Certificate2(bytes, password);

How to make it work on windows server without using chilkat library?


Solution

  • If your code is running in a web application under IIS:

    1. Go to IIS Manager
    2. Go to the application pool instance
    3. Click advanced settings
    4. Under Process model, set Load User Profile to true

    Else, try specifying the UserKeySet (it's possible that the PFX contains the "use the machine store" marker internally):

    var path = args[0]; var password = args[1]; var certificate2 = new X509Certificate2(path, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.EphemeralKeySet);

    Else, install the certificate on the local machine and try to load from store via thumbprint:

    If the above fails, then the .p12 file probably cannot be imported into Windows 2012 using the built-in Windows 2012 tools. To check that: "For each of your PKCS #12 files, you could try the following: issue the command certutil -asn | findstr /i "pb aes des sha" (replacing "" with the name of the PKCS #12 file).

    If the output starts like:

    | | | | | ; 1.2.840.113549.1.12.1.3 szOID_PKCS_12_pbeWithSHA1And3KeyTripleDES

    then it should be possible to import the PKCS #12 file into Windows 2016.

    If the output starts like:

    | | | | | ; 1.2.840.113549.1.5.13 szOID_PKCS_5_PBES2 | | | | | | ; 1.2.840.113549.1.5.12 szOID_PKCS_5_PBKDF2 | | | | | ; 2.16.840.1.101.3.4.1.42 aes256

    or similar, then the PKCS #12 file probably cannot be imported into Windows 2016 using the built-in Windows 2016 tools. You will have to recreate the PKCS #12 file using TripleDES and SHA1." - see thread: https://learn.microsoft.com/en-us/answers/questions/518605/importing-a-pkcs12-to-windows-server-2016.html