Java和SSL证书

我正在尝试使用安全套接字层(HTTPS)与我的PHP脚本建立连接,但我发现为了确保最高的安全性/有效性,我必须将我的网站使用的SSL证书导入到我的应用程序中……我不知道该怎么办的东西。

如果有帮助,我的SSL证书不是自签名的,而是由StartSSL提供的并且我使用的是Eclipse IDE。

有人能指出我正确的方向吗? 即我需要哪些文件,我应该在哪里导入它们以及我在Java中需要哪些代码等?

我发现为了确保最大安全性/有效性,我必须将我的网站使用的SSL证书导入我的应用程序

当你发表声明时,你是部分正确的。 您无需导入SSL证书。 导入StartSSL CA证书就足够了。

此外,没有将证书导入Java应用程序的事情。 Java中的SSL支持依赖于密钥库和信任库的概念,而不依赖于应用程序中打包的某些证书​​。 如果要发布要由最终用户下载和执行的应用程序,则无需在应用程序中发布证书或私钥。 私钥和关联的证书将存储在密钥库中,只有您可以访问。

应用程序的最终用户将依赖Java运行时内的SSL支持,这将使应用程序在validation服务器证书后建立到站点的SSL连接。 Java运行时在信任库中附带一组默认的CA证书,并且成功建立SSL连接的唯一先决条件是服务器的SSL证书由信任库中的一个CA颁发。 Java运行时的信任库中不存在StartSSL证书 ,至少从版本6开始,因此:

  • 您可以指示最终用户执行将StartSSL CA证书导入Java信任库的活动。 可能有助于包含此StartSSL论坛主题的链接 (仅需要前4个步骤才能将CA证书导入信任库), GitHub项目和此博客文章 ; 免责声明 – 我没有尝试使用其中任何一种,您应该使用它,风险自负。
  • 或者,您可以使用-Djavax.net.ssl.trustStore= -Djavax.net.ssl.trustStorePassword= JVM启动标志,使用您自己的信任库初始化您的应用程序,或者在初始化SSL连接之前执行以下代码:

     System.setProperty("javax.net.ssl.trustStore",""); System.setProperty("javax.net.ssl.trustStorePassword",""); 

    只有当您的应用程序是一个不恰好是applet的Java SE应用程序(或者对如何指定信任库具有类似限制的应用程序)时,这才是可行的方法。


阅读Java keytool文档也会有所帮助。

显然,邮件工程师出于某种原因不想给我们明确说明如何解决这个问题。 这就是我所做的

我们运行tomcat8并通过jersey web服务连接到mailgun API。 我按照这个用户的说明,它工作正常。 希望这有助于某人。

在1/22,由于Symantec的PKI基础设施设置为不受信任,我们更新了SSL证书。 某些旧版本的Java没有“DigiCert Global Root G2”CA.

有几种选择:

将“DigiCert Global Root G2”CA导入“cacerts”文件。 将您的JRE升级到8u91(或更高),其中包括此根。 要导入“DigiCert Global Root G2”,您可以从https://www.digicert.com/digicert-root-certificates.htm下载根目录。 确保您正在下载正确的根证书。

下载证书后,您需要使用如下命令将其导入:

keytool -import -trustcacerts -keystore / path / to / cacerts -storepass changeit -noprompt -alias digicert-global-root-g2 -file /path/to/digicert.crt您需要设置Java Keystore的路径和您下载的根证书的位置。


所以1. /path/to/digicert.crt是您刚刚下载的文件。 2. / path / to / cacerts – 这是在你的JRE路径中。 我“查找/ -name cacerts -print”这将帮助您快速找到文件系统上的所有java cacerts。 对我来说是/ usr / lib / jvm / java-7-openjdk-amd64 / jre / lib / security / cacerts

以下方法加载默认(cacerts)密钥库,检查是否安装了证书,如果没有,则安装它。 它消除了在任何服务器上手动运行keystore命令的需要。

它假定默认密钥库密码(changeit)未更改, CACERTS_PASSWORD更新CACERTS_PASSWORD 。 请注意,该方法在添加证书后保存密钥库,因此在证书永久存在于存储中后运行。

 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; /** * Add a certificate to the cacerts keystore if it's not already included */ public class SslUtil { private static final String CACERTS_PATH = "/lib/security/cacerts"; // NOTE: DO NOT STORE PASSWORDS IN PLAIN TEXT CODE, LOAD AT RUNTIME FROM A SECURE CONFIG // DEFAULT CACERTS PASSWORD IS PROVIDED HERE AS A QUICK, NOT-FOR-PRODUCTION WORKING EXAMPLE // ALSO, CHANGE THE DEFAULT CACERTS PASSWORD, AS IT IMPLORES YOU TO! private static final String CACERTS_PASSWORD = "changeit"; /** * Add a certificate to the cacerts keystore if it's not already included * * @param alias The alias for the certificate, if added * @param certInputStream The certificate input stream * @throws KeyStoreException * @throws NoSuchAlgorithmException * @throws CertificateException * @throws IOException */ public static void ensureSslCertIsInKeystore(String alias, InputStream certInputStream) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{ //get default cacerts file final File cacertsFile = new File(System.getProperty("java.home") + CACERTS_PATH); if (!cacertsFile.exists()) { throw new FileNotFoundException(cacertsFile.getAbsolutePath()); } //load cacerts keystore FileInputStream cacertsIs = new FileInputStream(cacertsFile); final KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType()); cacerts.load(cacertsIs, CACERTS_PASSWORD.toCharArray()); cacertsIs.close(); //load certificate from input stream final CertificateFactory cf = CertificateFactory.getInstance("X.509"); final Certificate cert = cf.generateCertificate(certInputStream); certInputStream.close(); //check if cacerts contains the certificate if (cacerts.getCertificateAlias(cert) == null) { //cacerts doesn't contain the certificate, add it cacerts.setCertificateEntry(alias, cert); //write the updated cacerts keystore FileOutputStream cacertsOs = new FileOutputStream(cacertsFile); cacerts.store(cacertsOs, CACERTS_PASSWORD.toCharArray()); cacertsOs.close(); } } } 

像这样使用它:

 SslUtil.ensureSslCertIsInKeystore("startssl", new FileInputStream("/path/to/cert.crt")); 

请查看以下文章: http : //stilius.net/java/java_ssl.php它包含代码示例,如果您尝试从代码访问脚本,可能会有所帮助。

请注意,您应该使用系统属性

 javax.net.ssl.keyStore javax.net.ssl.keyStorePassword 

使用keytool工具将SSL证书传递给JVM或将其导入JRE密钥库

我发现为了确保最大安全性/有效性,我必须导入SSL证书

不,你没有。 如果您的客户端尚未信任服务器证书的签名者,则只需要该步骤,只有在服务器证书是自签名或由内部CA签名的情况下才会出现。