I am writing a C# program that has to call an API endpoint that requires authentication via certificates.
I have got a .pfx file, which I can import in Windows and everything works fine, however the app must run in a Linux environment in a Docker container.
I can import crt files into the /etc/ssl/certs
folder in my Docker container just fine using the update-ca-certificates
command.
I have tried the following:
- Use openssl to to convert the pfx file into a crt/pem file that contains both the decrypted private key and the public key
-----BEGIN CERTIFICATE-----
abcd...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
abcd...
-----END RSA PRIVATE KEY-----
-
Use openssl to split both keys into separate files and import those
-
Leave the bag attributes that openssl spits out in the files
Bag Attributes
localKeyID: 01 00 00 00
friendlyName: XXX
subject=C = GB, O = 1111.1.1, O = XXX Limited, OU = devices, CN = XXX Limited
issuer=C = gb, O = 1111.1.1, O = YYY CAs, OU = YYY CA, OU = YYY Issuing CA
but the API always says I don't have a valid certificate.
Does anybody know what I'm doing wrong? Do the files have to be in a specific format? Perhaps in a different location?
My app finds the certificate just fine, so that's not the issue. The problem seems to be with the certificate itself.
Thanks in advance.
Best Answer
The certstore loader on Linux will never look at a private key attached on the bottom of a file in /etc/ssl/certs. (If you look at the cert object, you'll see
HasPrivateKey
isfalse
).If you want to use a cert with a private key you need to either load it directly from a PFX, load it from a PFX once to then add it to the
CurrentUser
\My
X509Store and then can use it from there, or load it from a multi-PEM intentionally, such as by callingX509Certificate2.CreateFromPemFile(pathToPem)
(orX509Certificate2.CreateFromPemFile(pathToCertPem, pathToKeyPem)
)Then change your app to look in CurrentUser\My instead of LocalMachine\CA (or LocalMachine\Root, wherever you happen to be pointing it).