61

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?

Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
nikel
  • 3,402
  • 11
  • 45
  • 71

6 Answers6

61

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-----

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

openssl x509 -in cacerts.pem -text

Bruno Grieder
  • 28,128
  • 8
  • 69
  • 101
  • Well,It had a lot of such units,i just modified it to include one.It got successfully installed.:) – nikel Mar 27 '12 at 13:33
  • 1
    Did you just add a BEGIN CERTIFICATE and END CERTIFICATE in between the entire data? I am also facing the same problem, can you please help me by saying what you did? – Rengasami Ramanujam May 10 '12 at 13:13
  • 3
    The lines should already be there. If they are not, your certificate is likely DER encoded (or invalid). To convert it do `openssl x509 -in mycert.der -inform DER -out myCert.pem -outform PEM`. To view and verify it `openssl -in myCert.pem -text`. The file must contain a single certificate. – Bruno Grieder May 10 '12 at 14:19
  • 18
    The problem can also be that `keytool` can be a little oversensitive to spaces and line endings. I tried to import the _Let's Encrypt_ certificate, and it failed because of that, and I fixed the certificate format with `openssl x509 -in broken.pem -out correct.pem` and it imported `correct.pem` without problems. – Stefan Seidel Mar 16 '16 at 09:45
  • 2
    lower case x509 is important! – Deian Jun 01 '19 at 14:54
42

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
alain.janinm
  • 19,951
  • 10
  • 65
  • 112
superlazy
  • 697
  • 1
  • 8
  • 15
  • 2
    What the doc doesn't make clear is that when you `-importcert` to an existing privatekey entry it expects a 'cert reply', which can be either a single cert or a chain including a PKCS7 using `CertificateFactory.generateCertificates` (with s at end) but when you `-importcert` to a new trustedcert entry it expects only one cert and NOT PKCS7 using `generateCertificate` (no s). If you want to trust multiple certs in a chain (and the point of chaining is that you don't need to) you must import them individually to different aliases. – dave_thompson_085 Feb 02 '19 at 12:11
  • I was also facing the issue of **keytool error: java.lang.Exception: Input not an X.509 certificate** I applied the above command on my pkcs12 certificate but changed -print_certs with -clcerts. One can see all pkcs12 commands with `openssl pkcs12 -help`. command is: `openssl pkcs12 -clcerts -in certfile.p12 -out newcertfile.cer` enter p12 cert password and then pass phrase for PEM. Note: I copied p12 cert to another place and then generated .cer from that to avoid any risk to original cert. – Noor Khan Nov 27 '21 at 03:10
9

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.

slim
  • 2,545
  • 1
  • 24
  • 38
XDanny322
  • 91
  • 2
  • 5
  • This was the issue for me also, I think because I copied the cert text directly out of the email from the certificate provider it left a space on the end of each line. – Continuity8 Sep 10 '17 at 05:10
  • 1
    Jesus Christ. This actually saved me. Thank you! – SirDerpington Apr 28 '20 at 15:27
  • To do this the easy way, if your text editor supports find/replace with regex (e.g. as Programmer's Notepad does), replace `\s*[\r\n]+\s*` with `\n`. – JohnLBevan Feb 19 '21 at 09:36
5

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

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
2

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.
LingYan Meng
  • 699
  • 4
  • 12
1

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