nikel
nikel

Reputation: 3564

Error Importing SSL certificate : Not an X.509 Certificate

I am trying to Update the SSL certificate in accordance with this post .

I am noob in certificates, so i followed this guide. But, when i enter

keytool -keystore mycacerts -storepass changeit -importcert -file "C:\Users\Noks\Desktop\cacerts.pem" -v

I get the error:

keytool error: java.lang.Exception: Input not an X.509 certificate
java.lang.Exception: Input not an X.509 certificate
        at sun.security.tools.KeyTool.addTrustedCert(KeyTool.java:1913)
        at sun.security.tools.KeyTool.doCommands(KeyTool.java:818)
        at sun.security.tools.KeyTool.run(KeyTool.java:172)
        at sun.security.tools.KeyTool.main(KeyTool.java:166)

How do i fix this?

Upvotes: 65

Views: 305212

Answers (8)

Bruno Grieder
Bruno Grieder

Reputation: 29874

Does your cacerts.pem file hold a single certificate? Since it is a PEM, have a look at it (with a text editor), it should start with

-----BEGIN CERTIFICATE-----

and end with

-----END CERTIFICATE-----

Make sure you do not have extra "white space" around these lines.

Finally, to check it is not corrupted, get hold of openssl and print its details using

openssl x509 -in cacerts.pem -text

Edit

As mentioned by @stefan-seidel below, try having openssl "regenerate" it using

openssl x509 -in broken.pem -out correct.pem

Upvotes: 71

Jeremy Hutchins
Jeremy Hutchins

Reputation: 299

I had another variant of issue compared to the above. My cert was valid as far as openssl was concerned when running openssl x509 -in <cert> -text - however, it turns out that I had an empty CN in the subject because of an issue when creating the cert. Looking at the output of the above command carefully, you can see what the subject of the cert is. If there is something there...

$ openssl x509 -in /tmp/cert.pem -text | grep Subject:
    Subject: CN = my-computer 

... then you are ok, but if the subject is empty ...

$ openssl x509 -in /tmp/cert-bad.pem -text | grep Subject:
    Subject: 

... then you'll get this error. Fix is to recreate the cert and ensure that it has a valid subject.

Upvotes: 0

Mari Faleiros
Mari Faleiros

Reputation: 738

I had this error and I had to change the encoding to UTF-8. Previously, my certificate file was encoded as UTF-16 LE and that's why neither keytool or openssl could recognize it.

Open your .pem file with Visual Studio Code and check the encoding on the footer:

enter image description here

If it's not UTF-8, click on the current encoding to open up the option to save with a different encoding:

enter image description here

Upvotes: 0

Mike Nakis
Mike Nakis

Reputation: 62120

As the various other answers to this question show, there are many different possible causes for this error message. The reason why it is happening to you may be totally different from the reasons why it is happening to me. And unfortunately, the error message is completely failing to point at the actual source of the problem, so it is completely unhelpful in troubleshooting. It is in fact entirely misleading.

So, instead of giving you yet one more from the myriad of possible causes of this error message, what I will do instead is show you how to troubleshoot this problem so as to find out what is causing it in your particular situation.

At work we commonly use the following two commands to enable some software to talk to various servers, for example to enable IntelliJ IDEA to talk to our internal maven repositories:

[Elevated]keytool 
    -printcert -rfc -sslserver maven.services.{our-company}.com:443 > public.crt

[Elevated]keytool
    -import -storepass changeit -noprompt -trustcacerts -alias services.{our-company}.com 
    -keystore lib\security\cacerts -file public.crt

Now, what sometimes happens is that the keytool -printcert command is unable to do its job, either due to misconfiguration, or simply because of temporary connectivity issues, such as the firewall preventing it, the user forgot to start his VPN, whatever. It is a fact of life that this may happen. This is not actually the problem.

The problem is that when the stupid tool encounters such an error, it does not emit the error message to the standard error device, it emits it to the standard output device!

So here is what ends up happening:

  • When you execute the first command, you don't see any error message, so you have no idea that it failed. However, instead of a key, the public.crt file now contains an error message saying keytool error: java.lang.Exception: No certificate from the SSL server.
  • When you execute the second command, it reads public.crt and it finds the text of the error message instead of a key in it, so it fails, saying keytool error: java.lang.Exception: Input not an X.509 certificate.

Bottom line is: after keytool -printcert ... > public.crt always dump the contents of public.crt to make sure it is actually a key and not an error message before proceeding to run keytool -import ... -file public.crt

Upvotes: 5

Pawel Zentala
Pawel Zentala

Reputation: 291

I had to remove spaces before the new line after -----BEGIN CERTIFICATE-----.

Upvotes: 2

LingYan Meng
LingYan Meng

Reputation: 774

I changed 3 things and then it works:

  1. There is a column of spaces, I removed them
  2. Changed the line break from windows CRLF to linux LF
  3. Removed the empty line at the end.

Upvotes: 2

XDanny322
XDanny322

Reputation: 101

This seems like an old thread, but I'll add my experience here. I tried to install a cert as well and got that error. I then opened the cer file with a txt editor, and noticed that there is an extra space (character) at the end of each line. Removing those lines allowed me to import the cert.

Hope this is worth something to someone else.

Upvotes: 10

superlazy
superlazy

Reputation: 806

Many CAs will provide a cert in PKCS7 format.

According to Oracle documentation, the keytool commmand can handle PKCS#7 but sometimes it fails

The keytool command can import X.509 v1, v2, and v3 certificates, and PKCS#7 formatted certificate chains consisting of certificates of that type. The data to be imported must be provided either in binary encoding format or in printable encoding format (also known as Base64 encoding) as defined by the Internet RFC 1421 standard. In the latter case, the encoding must be bounded at the beginning by a string that starts with -----BEGIN, and bounded at the end by a string that starts with -----END.

If the PKCS7 file can't be imported try to transform it from PKCS7 to X.509:

openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer

Upvotes: 43

Related Questions