我正在尝试使用安全套接字层(HTTPS)与Java中的PHP脚本建立连接,但我发现为了确保最大的安全性/有效性,我必须将我的网站使用的SSL证书导入我的应用程序…一件我不知道怎么做的事。
如果它有帮助,我的SSL证书不是自签名的,而是由StartSSL提供的,我正在使用Eclipse IDE。
谁能给我指个正确的方向?例如,我需要哪些文件,我应该在哪里导入它们,我需要哪些Java代码,等等?我已经发现,为了确保最大的安全性/有效性,我必须将我的网站使用的SSL证书导入我的应用程序
你说的那句话有一部分是对的。您不需要导入SSL证书。导入StartSSL CA证书就足够了。
此外,不存在将证书导入Java应用程序这样的事情。Java中的SSL支持依赖于密钥库和信任库的概念,而不是依赖于应用程序中打包的某些证书。如果您发布的应用程序供最终用户下载和执行,则不需要在应用程序中发布证书或私钥。私钥和相关的证书将存储在密钥存储库中,只有您可以访问。
应用程序的最终用户将依赖于Java运行时中的SSL支持,这将使应用程序能够在验证服务器证书后建立到站点的SSL连接。Java运行时附带了信任存储库中的一组默认CA证书,成功建立SSL连接的唯一先决条件是服务器的SSL证书由信任存储库中的一个CA颁发。 StartSSL的证书不存在于Java运行时的信任存储库中,至少从版本6开始是这样,因此:
- 您可以指示您的最终用户执行将StartSSL CA证书导入Java信任库的活动。可能有帮助的链接包括这个StartSSL论坛线程(只需要将CA证书导入信任库的前4步),GitHub项目和这篇博客文章;免责声明-我没有尝试使用任何这些,您应该自行承担风险。
-
或者,您可以使用
-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>");
只有当您的应用程序是Java SE应用程序而不是applet(或对如何指定信任库具有类似限制的应用程序)时,这才是可行的方法。
阅读Java keytool文档也会有所帮助。
以下方法加载默认(cacerts)密钥存储库,检查是否安装了证书,如果没有安装,则安装证书。它消除了在任何服务器上手动运行keystore
命令的需要。
假设默认的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"));
显然mailgun工程师出于某种原因不想给我们明确的说明如何解决这个问题。这就是我所做的
我们运行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.//digicert/路径。CRT就是你刚下载的文件。2./path/to/cacerts—这是您的JRE路径。我"find/-name cacerts -print"这将帮助您快速找到文件系统上的所有java cacerts。对我来说,它是/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts
看看下面的文章:http://stilius.net/java/java_ssl.php它包含代码示例,这可能有助于在情况下,如果你试图从代码访问你的脚本。
请注意,您应该使用系统属性
javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword
将SSL证书传递给JVM或使用keytool工具将其导入JRE密钥库
我已经发现,为了确保最大的安全性/有效性,我必须导入SSL证书
不,你没有。只有当您的客户端不相信服务器证书的签名者时,您才需要该步骤,这只有在服务器证书是自签名或由内部CA签名时才会出现
这篇文章包含更改信任存储的密码和在那里添加其他证书的代码:
thetechawesomeness.ideasmatter.info