导入SSL证书错误:不是X.509证书。

61
我正在尝试根据这篇文章更新SSL证书。
我对证书一无所知,因此我按照这个指南进行操作。但是,当我输入时,出现了问题。
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)

我该如何解决这个问题?


我认为该命令在Java 1.6或更高版本中完全正常运行。 - Chaitanya Gudala
6个回答

61
你的cacerts.pem文件是否只包含一个证书?由于它是PEM格式的,请使用文本编辑器查看一下,它应该以"-----BEGIN CERTIFICATE-----"开头,并以"-----END CERTIFICATE-----"结尾。
最后,为了检查它是否损坏,获取openssl并使用以下命令打印其详细信息:
openssl x509 -in cacerts.pem -text

编辑

如@stefan-seidel所提到的,尝试使用openssl进行"重新生成",命令如下:
openssl x509 -in broken.pem -out correct.pem

好的,它有很多这样的单元,我只是修改了它以包括一个。它已经成功安装了。:) - nikel
1
你刚刚是在整个数据之间添加了BEGIN CERTIFICATE和END CERTIFICATE吗?我也遇到了同样的问题,你能告诉我你做了什么来帮助我吗? - Rengasami Ramanujam
3
这些行应该已经存在了。如果没有出现,你的证书很可能是DER编码(或无效的)。要转换它,请执行“openssl x509 -in mycert.der -inform DER -out myCert.pem -outform PEM”命令。要查看和验证它,请运行“openssl -in myCert.pem -text”。文件必须包含一个单独的证书。 - Bruno Grieder
19
问题可能在于 keytool 对于空格和换行符有些敏感。我尝试导入 Let's Encrypt 的证书,由于此原因失败了,后来我用命令 openssl x509 -in broken.pem -out correct.pem 修复了证书格式,然后成功地导入了 correct.pem - Stefan Seidel
2
小写的 x509 很重要! - Deian
@StefanSeidel - 使用 openssl x509 -in <file> -out <file> 是个绝妙的主意。很棒的想法。 - undefined

42

许多CA会提供PKCS7格式的证书。

根据Oracle文档,keytool命令可以处理PKCS#7格式,但有时会失败。

keytool命令可以导入X.509 v1、v2和v3证书以及由该类型证书组成的PKCS#7格式的证书链。要导入的数据必须以二进制编码格式或可打印编码格式(也称为基于Internet RFC 1421标准定义的Base64编码)提供。在后一种情况下,编码必须在开头由一个字符串限定,该字符串以-----BEGIN开头,并且在结尾由一个以-----END开头的字符串限定。

如果无法导入PKCS7文件,请尝试将其从PKCS7转换为X.509:

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

2
文档没有明确说明的是,当您使用“-importcert”到现有的私钥条目时,它期望一个“证书回复”,可以是单个证书或包括PKCS7的链,使用CertificateFactory.generateCertificates(带有s),但是当您将“-importcert”导入新的trustedcert条目时,它只期望一个证书而不是使用generateCertificate(没有s)的PKCS7。如果您想信任链中的多个证书(链接的目的是您不需要),则必须将它们分别导入到不同的别名中。 - dave_thompson_085
我也遇到了“keytool error: java.lang.Exception: Input not an X.509 certificate”的问题。我在我的pkcs12证书上应用了上述命令,但将-print_certs更改为-clcerts。可以使用openssl pkcs12 -help查看所有pkcs12命令。命令是:openssl pkcs12 -clcerts -in certfile.p12 -out newcertfile.cer输入p12证书密码,然后输入PEM密码。注意:我将p12证书复制到另一个地方,然后从那里生成了.cer文件,以避免对原始证书造成任何风险。 - Noor Khan

9
这似乎是一个旧帖子,但是我会在这里分享我的经验。 我也尝试安装证书,并遇到了该错误。 然后,我用文本编辑器打开了cer文件,并注意到每行末尾都有一个额外的空格(字符)。 删除那些行允许我导入证书。
希望这对其他人有所帮助。

这对我来说也是个问题,我认为是因为我直接从证书提供者的电子邮件中复制了证书文本,在每行末尾留下了一个空格。 - Continuity8
1
耶稣基督。这实际上拯救了我。谢谢! - SirDerpington
为了简单起见,如果您的文本编辑器支持使用正则表达式查找/替换(例如程序员记事本),请将\s*[\r\n]+\s*替换为\n - JohnLBevan

5
正如其他回答所示,此错误消息可能有许多不同的可能原因。它发生在你身上的原因可能与我遇到的原因完全不同。不幸的是,错误消息完全没有指出问题的实际来源,因此在故障排除时完全无用。事实上,它是完全误导性的。
因此,我将向您展示如何解决这个问题,以找出在您特定情况下造成它的原因,而不是给您提供更多可能引起此错误消息的原因之一。
在工作中,我们通常使用以下两个命令来启用某些软件与各种服务器通信,例如使 IntelliJ IDEA 能够与我们内部的 maven 存储库通信:
[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

现在,有时候会出现keytool -printcert命令无法执行其工作的情况,这可能是由于错误配置或临时连接问题引起的,例如防火墙阻止了它,用户忘记启动VPN等。这可能是生活中常有的事实。这实际上并不是问题。
问题在于当该工具遇到此类错误时,它不会向标准错误设备发出错误消息,而是向标准输出设备发出消息!
以下就是发生的情况:
- 当您执行第一个命令时,您不会看到任何错误消息,因此您不知道它失败了。但是,public.crt文件不再包含密钥,而是包含了一个错误消息,其中写着keytool error: java.lang.Exception: No certificate from the SSL server。 - 当您执行第二个命令时,它读取了public.crt,发现其中的文本是错误消息,而不是密钥,因此它失败,并显示keytool error: java.lang.Exception: Input not an X.509 certificate
最重要的是,在运行keytool -import ... -file public.crt之前,始终要将public.crt的内容转储出来,以确保它实际上是一个密钥,而不是错误消息。

2

我做了三件事情,然后它就可以工作了:

  1. 有一列空格,我把它们移除了
  2. 将换行符从Windows的CRLF格式改为Linux的LF格式
  3. 移除了末尾的空行

1

-----BEGIN CERTIFICATE-----之后的换行符前,我必须删除空格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接