我正在尝试使用安全套接字层(HTTPS)与我的PHP脚本建立连接,但我发现为了确保最高的安全性/有效性,我必须导入我的网站使用的SSL证书进入我的申请......我不知道该怎么做。
如果有帮助,我的SSL证书不是自签名的,而是由StartSSL提供的,而我正在使用Eclipse IDE。
有人能指出我正确的方向吗?即我需要哪些文件,我应该在哪里导入它们以及我需要用Java编写哪些代码?
答案 0 :(得分:27)
我发现要确保最高安全性/有效性,我必须将我的网站使用的SSL证书导入我的应用程序
当你发表声明时,你是部分正确的。您无需导入SSL证书。只需导入StartSSL CA证书即可。
此外,没有将证书导入Java应用程序的事情。 Java中的SSL支持依赖于密钥库和信任库的概念,而不依赖于应用程序中打包的某些证书。如果您要发布要由最终用户下载和执行的应用程序,则无需在应用程序中发布证书或私钥。私钥和关联的证书将存储在密钥库中,只有您可以访问。
应用程序的最终用户将依赖Java运行时内的SSL支持,这将使应用程序在验证服务器证书后建立到站点的SSL连接。 Java运行时在信任库中附带一组默认的CA证书,并且成功建立SSL连接的唯一先决条件是服务器的SSL证书由信任库中的一个CA颁发。 StartSSL的证书不存在于Java运行时的信任库中 ,至少从版本6开始,因此:
或者,您可以使用-Djavax.net.ssl.trustStore=<path_to_truststore> -Djavax.net.ssl.trustStorePassword=<truststore_password>
JVM启动标志使用您自己的信任库初始化您的应用程序,或者在初始化SSL连接之前执行以下代码:
System.setProperty("javax.net.ssl.trustStore","<path_to_truststore>");
System.setProperty("javax.net.ssl.trustStorePassword","<truststore_password>");
这是一种可行的方法,只有当您的应用程序是一个不恰好是applet的Java SE应用程序时(或者对如何指定信任库具有类似限制的应用程序)。
答案 1 :(得分:2)
显然,邮件工程师出于某种原因不想就如何解决这个问题向我们提供明确的指示。这就是我所做的
我们运行tomcat8并通过jersey web服务连接到mailgun API。我按照这个用户的说明,它工作正常。希望这有助于某人。
在1/22,由于赛门铁克的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
答案 2 :(得分:1)
以下方法加载默认(cacerts)密钥库,检查是否安装了证书,如果没有,则安装它。它消除了在任何服务器上手动运行keystore
命令的需要。
它假定默认密钥库密码(changeit)未更改,否则更新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"));
答案 3 :(得分:0)
查看以下文章:http://stilius.net/java/java_ssl.php 它包含代码示例,如果您尝试从代码访问脚本,可能会有所帮助。
请注意,您应该使用系统属性
javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword
使用keytool工具将SSL证书传递给JVM或将其导入JRE密钥库
答案 4 :(得分:0)
我发现要确保最大的安全性/有效性 导入SSL证书
不,不。如果您的客户端尚未信任服务器证书的签名者,则只需要该步骤,只有在服务器证书是自签名或签名的情况下才会出现这种情况。由内部CA.
答案 5 :(得分:0)
该文章包含用于更改信任库密码并在其中添加其他证书的代码: