I get the error: unable to load certificates
myserver.crt
needs to be in PEM format. Does it have ----- BEGIN CERTIFICATE -----
and ----- END CERTIFICATE -----
?
myserver.crt
should actually be a chain of certificates (and not just the one server certificate). The chain should include all intermediate certificates needed by the client to verify the chain.
You send all the intermediate certificates to solve the «which directory» problem. The «which directory» is a well know problem in PKI. Essentially, the client does not know where to go to fetch the missing intermediate cert. To avoid the problem, you send all intermediates.
I often use Startcom because they offer free Class 1 certificates. When I get the signed server certificate from them (for example, www-example-com.crt), I add their Class 1 Server Intermediate to it. I get their Class 1 Server Intermediate from their website at Startcom CA certs. The one I use is sub.class1.server.ca.pem
.
With the www-example-com.crt
, my server certificate looks like:
$ cat www-example-com.crt
-----BEGIN CERTIFICATE-----
< My Server Certificate >
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
< Startcom Intermediate >
-----END CERTIFICATE-----
For completeness, the private key (for example, www-example-com.key
) is also in PEM format. It uses -----BEGIN RSA PRIVATE KEY-----
and -----END RSA PRIVATE KEY-----
.
With my server certificate in PEM format (and with the required intermediates) and private key, I then issue the following (which looks like the same command you are using):
openssl pkcs12 -export -in www-example-com.crt -inkey www-example-com.key -out www-example-com.p12
When clients connect, they use the Startcom CA. So, to test the connection (after loading into IIS):
openssl s_client -connect www.example.com:443 -CAfile startcom-ca.pem
The command should complete with «Verify OK»:
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 37E5AF0EE1745AB2...
Session-ID-ctx:
Master-Key: 7B9F8A79D3CC3A41...
Key-Arg : None
Start Time: 1243051912
Timeout : 300 (sec)
Verify return code: 0 (ok)
I have also tried this: x509 -text -in myserver.key and received the error…
x509
is for certificates. If you want to dump a key, use OpenSSL’s pkey
command. See the docs on OpenSSL’s pkey(1)
command.
For years, I have been using the following one-liner to alter the «CSP» setting of any given PFX, without any issue:
openssl pkcs12 -in original.pfx | openssl pkcs12 -export -CSP 'blah...' -out fixed.pfx
«Recently», this has started failing with the error message:
Unable to load certificates
I’m running from distro-packaged versions, which appear to be based on 1.0.2g
(Ubuntu Xenial) and 1.0.1e-fips
(CentOS 6), so I know I’m not running latest source, and I don’t want to raise a bug based on the behaviour of these older versions, without first verifying my findings and understanding (hence the question).
My understanding is that openssl pkcs12
accepts input from stdin by default when -in
is not passed: input should consist of PEM-armoured base64 objects, where at least one must be a certificate and (where -inkey
is not passed) the other must be its key.
This understanding is based on the documentation for -in
and -inkey
in man pkcs12
, which reads:
-in
filename
The filename to read certificates and private keys from, standard input by default. They must all be in PEM format. The order doesn’t matter but one private key and its corresponding certificate should be present. If additional certificates are present they will also be included in the PKCS#12 file.
-inkey
filename
file to read private key from. If not present then a private key must be present in the input file.
But, at the moment, I can’t get any stdin-based form of openssl pkcs12
to actually parse input to that understanding.
So far, my repeatable test is:
~$
openssl req -x509 -subj '/CN=test.example.org' -newkey rsa:2048 -keyout src.key -out src.crt
Generating a 2048 bit RSA private key .......+++ ..............................................................................................................................................+++ writing new private key to 'src.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: -----
~$
openssl pkcs12 -export -in src.crt -inkey src.key -out src.pfx
Enter pass phrase for test.key: Enter Export Password: Verifying - Enter Export Password:
~$
rm src.crt src.key
PFX is usually created elsewhere and given to me to fix, so no access to original key and cert
~$
openssl pkcs12 -in src.pfx | openssl pkcs12 -export -CSP 'Microsoft Enhanced RSA and AES Cryptographic Provider' -out fixed.pfx
Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Enter pass phrase: unable to load certificates
Things that work
-
Parsing the output of
pkcs12
asx509
:
~$
openssl pkcs12 -in src.pfx | openssl x509 -text
Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Certificate: Data: Version: 3 (0x2) Serial Number: 12174721212992351602 (0xa8f54c7053d26d72) Signature Algorithm: sha256WithRSAEncryption ...
-
Parsing the output of
pkcs12
aspkey
:
~$
openssl pkcs12 -in src.pfx | openssl pkey -text
Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Enter pass phrase: -----BEGIN PRIVATE KEY----- MIIE...Xw== -----END PRIVATE KEY----- Private-Key: (2048 bit) modulus: 00:da:15:5e:77:ac:91:c4:88:3a:8f:a3:02:f7:c2: 58:8a:d1:18:e0:fd:66:58:2b:22:5c:30:58:fe:b9: ...
-
Exporting to intermediary temp files, then using
-in
and-inkey
:
~$
openssl pkcs12 -in src.pfx | openssl x509 -out inter.crt
Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase:
~$
openssl pkcs12 -in src.pfx | openssl pkey -out inter.key
Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Enter pass phrase:
~$
openssl pkcs12 -export -in inter.crt -inkey inter.key -out fixed.pfx -CSP 'Microsoft Enhanced RSA and AES Cryptographic Provider'
Enter Export Password: Verifying - Enter Export Password:
-
Bash process substitution (with appropriate password handling):
~$
export PASSWD=blah
~$
openssl pkcs12 -export -in <(openssl pkcs12 -in src.pfx -passin env:PASSWD -nokeys | openssl x509 -outform PEM) -inkey <(openssl pkcs12 -in src.pfx -nocerts -passin env:PASSWD -passout env:PASSWD | openssl pkey -outform PEM -passin env:PASSWD) -CSP 'Microsoft Enhanced RSA and AES Cryptographic Provider' -out fixed.pfx -passout env:PASSWD
MAC verified OK MAC verified OK
Related things that don’t work
-
Concatenating the output of
x509
andpkey
files, and passing by stdin:
~$
cat inter.crt inter.key | openssl pkcs12 -export -CSP 'Microsoft Enhanced RSA and AES Cryptographic Provider' -out inter.pfx
unable to load certificates
-
Executing both
x509
andpkey
in a subshell, and passing by stdin:
~$
( openssl pkcs12 -in test.pfx | openssl x509 -outform PEM; openssl pkcs12 -in test.pfx | openssl pkey -outform PEM; ) | openssl pkcs12 -export -CSP 'Microsoft Enhanced RSA and AES Cryptographic Provider' -out fixed.pfx
Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Enter pass phrase: unable to load certificates
We may come across the OpenSSL “Unable to load certificate” error if we paste the cert from a browser.
It is most likely that we may miss the CR and LF characters making OpenSSL not read/load the cert file.
As part of our Server Management Services, we assist our customers with several OpenSSL queries.
Today, let us see how our techs fix this error.
OpenSSL “Unable to load certificate” error
In order to begin, our Support Techs recommend having OpenSSL 0.9.7a and RHEL5.
Most often, the error message will look like the following:
Unable to load certificate PEM routines PEM_read_bio:bad base64 decode:pem_libc
In this case, we need to make sure to enclose cert within BEGIN CERTIFICATE and END CERTIFICATE statements.
openssl error:0906D064:PEM routines:PEM_read_bio:bad base64 decode
Another scenario is the above error. Recently for one of our customers, Java keytool could read an X509 certificate file, but OpenSSL could not.
He thought it must be in DER instead of PEM,” but it was in PEM (plain text).
This is because OpenSSL is picky about PEM certificate formatting.
Moving ahead, let us see how our Support Techs fix these issues.
1. First and foremost, the file must contain:
—–BEGIN CERTIFICATE—–
It should be in a separate line.
2. In addition, each line of “gibberish” must be 64 characters wide.
3. And the file must end with:
—–END CERTIFICATE—–
Like the prior, this should also be terminated with a new line.
4. Then we ensure, not to save the cert text with Word. We save it in ASCII.
5. Similarly, we should not mix DOS and UNIX style line terminations.
Here are a few steps our Support Techs employ to normalize the certificate:
1. First, we run it through dos2unix:
dos2unix cert.pem
2. Then we run it through the fold:
fold -w 64 cert.pem
[Couldn’t fix the error? We can help you fix it]
Conclusion
In short, we saw how our Support Techs resolve the OpenSSL queries for our customers.
PREVENT YOUR SERVER FROM CRASHING!
Never again lose customers to poor server speed! Let us help you.
Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.
GET STARTED
Let me explain what all of these files are and what they mean. Then the solution will become more obvious:
What is a public and private key?
Public and private keys are two parts of a key, used for asymmetric encryption. They are mathematically related, and are generated together. The public key, as the name suggests, can be made public without any loss of security. In fact, it’s necessary so others can send messages.
When sending a message, the sender uses the recipients public key to encrypt a message. The recipient then uses their corresponding private key to decrypt the message.
While there are no standardized extensions for public and private key files, commonly chosen names are myname.pub.pem
and myname.priv.pem
. Some people use myname.pub.key
and myname.key
(or myname.priv.key
), but on Linux systems, extensions are not important.
What is a certificate?
A certificate is a public key, which was signed by another certificate. The way this works is that someone creates a certificate signing request, which contains their public key and is signed by their private key. The request also contains other identification information, such as domain name, e-mail address, etc., depending on the intended purpose of the certificate. The request is then sent to a certificate authority, which validates this information somehow and then signs the request (or not).
The result of this signature is a certificate, which is basically this:
Hello, my name is Alice and my public key is
11:22:33:44:55:66:77:88 99:00:AA:BB:CC:DD:EE:FF
Bob has signed that I am Alice. Bob’s certificate is below:
Hello, my name is Bob and my public key is
AB:CD:EF:01:02:03:04:05 06:07:08:09:10:12:13:14
Claus has signed that I am Bob. Claus’ certificate is below:
…
This would keep going until someone eventually signs their own certificate. This means they claim to be who they are, and you should just trust them. These certificates are called «root certificates» and are shipped together with your operating system.
Since a certificate is, in it’s most basic sense, a public key with «stuff added to it», you still need the corresponding private key to use it. You can download certificates from other websites too, but without the corresponding private key, you cannot use them in any way.
What is a PKCS #12 file?
In the broadest terms, a PKCS #12 file is a bundle of cryptographic things. As stated above, in order to use a certificate, you need the corresponding private key. To make things «simple» for deployment, the certificate and the private key are often bundled together in one PKCS #12 file (e.g. myname.pfx
).
Of course, PKCS #12 offers much more, and Wikipedia gives a good overview over its features.
So, what is the problem?
The problem is in the following line:
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt
What this does is take a certificate (certificate.crt
) and a private key (privateKey.key
) and bundles them into one PKCS #12 file (certificate.pfx
).
The error «unable to load private key» and «Expecting: ANY PRIVATE KEY» indicate that what you provided is no private key. What exactly the reason for this is can’t be deducted from the information you provided, but here are some wild guesses:
- You didn’t see that
privateKey.key
was a placeholder and your file is named differently. - You didn’t change into the correct working directory where the certificate and private key were.
- You used your public key instead of your private key.
- You don’t have correct permissions for your private key.
- Your private key is not in a recognized format (e.g. newline shenanigans)
I hope this explains the situation well enough and gives you enough pointers to go by to find a solution.