如何在不使用 keytool 命令行实用程序的情况下导入新的 Java CA 证书?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1650596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I import a new Java CA cert without using the keytool command line utility?
提问by Alexander Ljungberg
Executive summary: how do I install a new root certificate into Java using Java code?
执行摘要:如何使用 Java 代码将新的根证书安装到 Java 中?
We have a desktop application which accesses various web services. Recently one of them switched their SSL certificate to one signed by Trustwave. While the Trustwave SSL certificates are accepted by regular internet browsers, Java does not seem to come with the prerequisite root certificates, and we lost access to the given web service with the following error message:
我们有一个访问各种网络服务的桌面应用程序。最近他们中的一个将他们的 SSL 证书换成了由 Trustwave 签名的证书。虽然 Trustwave SSL 证书被常规互联网浏览器接受,但 Java 似乎没有附带必备的根证书,我们无法访问给定的 Web 服务并显示以下错误消息:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
We got a temporary reprieve by convincing the provider to switch back to Verisign but when they switch back we have to be ready. So I need our desktop software to automatically install the Trustwave root certificate as needed. Our customers are not tech savvy enough to use the keytool command and I would rather not script it since that strikes me as a fragile solution (separate implementations for Mac and PC, the struggle against Vista execution restrictions, trouble finding the correct JRE to install into, etc).
通过说服提供商切换回威瑞信,我们获得了暂时的缓刑,但当他们切换回来时,我们必须做好准备。所以我需要我们的桌面软件根据需要自动安装 Trustwave 根证书。我们的客户对使用 keytool 命令的技术不够了解,我宁愿不编写脚本,因为这让我觉得这是一个脆弱的解决方案(Mac 和 PC 的单独实现,与 Vista 执行限制的斗争,找不到正确的 JRE 以安装到, 等等)。
I imagine the keytool uses Java internally. What command could I use within Java to replicate the functionality of keytool and install the root certificate programmatically?
我想 keytool 在内部使用 Java。我可以在 Java 中使用什么命令来复制 keytool 的功能并以编程方式安装根证书?
采纳答案by Yishai
回答by Vineet Reynolds
IMHO, Sun has not exposed keytool via an API, primarily to prevent developers from modifying the set of trusted CAs. I can very imagine attackers exploiting such code to insert their own root certificates into the trust store compromising the very model of the trust store.
恕我直言,Sun 没有通过 API 公开 keytool,主要是为了防止开发人员修改受信任的 CA 集。我可以想象攻击者利用这些代码将他们自己的根证书插入信任库,从而破坏了信任库的模型。
In fact, if you look at the source of the KeyTool class (sun.security.tools package), not only is it final, it also has a private constructor preventing any caller from creating an instance of the KeyTool class from code. KeyTool does have a main method, making the commandline (and hence an OS user) possibly the only manner in which one can initialize and communicate with KeyTool.
事实上,如果你查看 KeyTool 类的源代码(sun.security.tools 包),它不仅是最终的,它还有一个私有构造函数,防止任何调用者从代码中创建 KeyTool 类的实例。KeyTool 确实有一个 main 方法,使命令行(以及操作系统用户)可能是人们可以初始化和与 KeyTool 通信的唯一方式。
The only (simplistic) approaches left would be:
剩下的唯一(简单)方法是:
- Initialize keytool as a process from the application, and pass commandline arguments to install the root CA certificate. This alone is a bad idea, and I would recommend notifying the user as to what is occuring.
- Avoid the use of keytool and instead provide users with instructions on how to install the root CA using Keymanor KeyTool IUI. Speaking for myself only here, I prefer the latter.
- 将 keytool 初始化为应用程序的一个进程,并传递命令行参数以安装根 CA 证书。这本身是一个坏主意,我建议将发生的情况通知用户。
- 避免使用 keytool,而是向用户提供有关如何使用Keyman或KeyTool IUI安装根 CA 的说明。在这里仅就我自己而言,我更喜欢后者。
回答by Richard Perfect
You could always invoke KeyTool as a process Runtime.exec(...).
您始终可以将 KeyTool 作为一个进程来调用Runtime.exec(...)。
回答by farcepest
Command-line solution.On the Mac, the Java home is /Library/Java/Home. Try:
命令行解决方案。在 Mac 上,Java 主目录是 /Library/Java/Home。尝试:
$ sudo -i
# cd /Library/Java/Home
# keytool -import -trustcacerts -alias CAName -file CA.crt -keystore lib/security/cacerts
Substitute CAName with the name of your CA, and CA.crt with a path to your certificate file (PEM works). It will prompt for a keystore password. The default password is given in the linked article.
将 CAName 替换为您的 CA 的名称,并将 CA.crt 替换为您的证书文件的路径(PEM 有效)。它将提示输入密钥库密码。默认密码在链接的文章中给出。
I had to do this for one of RapidSSL's CA certs.
我必须为 RapidSSL 的 CA 证书之一执行此操作。
回答by notalbert
Sun published this code to create an updated version of your cacerts file based on any target host running https with any certs:
Sun 发布了此代码,以根据运行 https 和任何证书的任何目标主机创建 cacerts 文件的更新版本:
https://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java
https://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java
Your new cacerts will be named jssecacerts in the current directory. Just copy that new file over your jre/lib/security/cacerts file.
您的新 cacerts 将在当前目录中命名为 jssecacerts。只需将该新文件复制到您的 jre/lib/security/cacerts 文件中即可。
I make no comment about the security of your new cacerts file.
我不对您的新 cacerts 文件的安全性发表评论。
回答by Miguel Ping
If you want to install the certificate to the trusted root's keystore on the desktop machine, you will need permission to do that. It's the same with the keytool, you need a password to access the trusted root's keystore. If you want to be quick-n-dirty, you can
如果您想将证书安装到桌面计算机上受信任根的密钥库,您将需要这样做的权限。与keytool相同,您需要密码才能访问受信任根的密钥库。如果你想快速肮脏,你可以
- write the certificate to a file or a byte stream or whatever
- import using
KeyToolclass (sun.security.tools.KeyTool)
- 将证书写入文件或字节流或其他任何内容
- 使用
KeyTool类 (sun.security.tools.KeyTool)导入
But IMHO if the certificate is not valid, then it is not trustworthy. I would say there's a good reason for that.
但恕我直言,如果证书无效,则它不值得信赖。我会说这是有充分理由的。

