如何在不使用keytool命令行实用程序的情况下导入新的Java CA证书?

执行摘要:如何使用Java代码将新的根证书安装到Java中?

我们有一个桌面应用程序,可以访问各种Web服务。 最近其中一人将他们的SSL证书改为由Trustwave签署的证书。 虽然常规Internet浏览器接受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 

我们通过说服提供商切换回Verisign来暂时缓解,但当他们切换回来时我们必须做好准备。 所以我需要我们的桌面软件根据需要自动安装Trustwave根证书。 我们的客户对于使用keytool命令不够科技,我宁愿不编写脚本,因为这让我觉得它是一个脆弱的解决方案(Mac和PC的单独实现,对Vista执行限制的斗争,无法找到正确的JRE安装到等)。

我想keytool在内部使用Java。 我可以在Java中使用什么命令来复制keytool的function并以编程方式安装根证书?

我不知道这是否可行,但您可以实现自己的TrustManager以允许此连接或此CA. 以下是基础知识。

恕我直言,Sun尚未通过API公开keytool,主要是为了防止开发人员修改可信CA的集合。 我可以想象攻击者利用这些代码将自己的根证书插入到信任存储中,从而危及信任存储的模型。

实际上,如果你查看KeyTool类(sun.security.tools包)的源代码,它不仅是最终的,它还有一个私有构造函数,阻止任何调用者从代码中创建KeyTool类的实例。 KeyTool确实有一个main方法,使命令行(以及操作系统用户)成为可以初始化和与KeyTool通信的唯一方式。

剩下的唯一(简单化)方法是:

  • 将keytool初始化为来自应用程序的进程,并传递命令行参数以安装根CA证书。 仅这一点是一个坏主意,我建议通知用户发生了什么。
  • 避免使用keytool,而是向用户提供有关如何使用Keyman或KeyTool IUI安装根CA的说明 。 仅在这里为自己说话,我更喜欢后者。

您始终可以将KeyTool作为进程Runtime.exec(...)调用。

如果要将证书安装到桌面计算机上受信任的根密钥库,则需要获得该权限。 与keytool相同,您需要密码才能访问受信任的根密钥库。 如果你想快点肮脏,你可以

  • 将证书写入文件或字节流或其他任何内容
  • 使用KeyTool类导入( sun.security.tools.KeyTool

但恕我直言,如果证书无效,那么它是不值得信赖的。 我想说这是有充分理由的。

命令行解决方案。 在Mac上,Java主目录是/ Library / Java / Home。 尝试:

 $ sudo -i # cd /Library/Java/Home # keytool -import -trustcacerts -alias CAName -file CA.crt -keystore lib/security/cacerts 

使用CA的名称替换CAName,使用证书文件的路径替换CA.crt(PEM可以正常工作)。 它将提示输入密钥库密码。 默认密码在链接文章中给出。

我不得不为RapidSSL的CA证书之一做这件事。

Sun发布此代码以基于任何运行https且具有任何证书的目标主机创建cacerts文件的更新版本:

https://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java

您的新cacerts将在当前目录中命名为jssecacerts。 只需将该新文件复制到jre / lib / security / cacerts文件中即可。

我对您的新cacerts文件的安全性不做任何评论。