Java 和 SSL 证书
我正在尝试使用安全套接字层(HTTPS)在Java中与我的PHP脚本建立连接,但我发现为了确保最大的安全性/有效性,我必须将我的网站使用的SSL证书导入到我的应用程序中...我不知道该怎么做。
如果它有帮助,我的SSL证书不是自签名的,而是由StartSSL提供的,我正在使用Eclipse IDE。
任何人都可以为我指出正确的方向吗?即,我需要哪些文件,我应该在哪里导入它们以及我需要Java中的哪些代码等?
我正在尝试使用安全套接字层(HTTPS)在Java中与我的PHP脚本建立连接,但我发现为了确保最大的安全性/有效性,我必须将我的网站使用的SSL证书导入到我的应用程序中...我不知道该怎么做。
如果它有帮助,我的SSL证书不是自签名的,而是由StartSSL提供的,我正在使用Eclipse IDE。
任何人都可以为我指出正确的方向吗?即,我需要哪些文件,我应该在哪里导入它们以及我需要Java中的哪些代码等?
我发现为了确保最大安全性/有效性,我必须将我的网站使用的SSL证书导入到我的应用程序中
当你做出这个声明时,你是部分正确的。您无需导入 SSL 证书。导入 StartSSL CA 证书就足够了。
此外,没有将证书导入 Java 应用程序这样的事情。Java 中的 SSL 支持依赖于密钥库和信任库的概念,而不是应用程序中打包的某些证书。如果要发布应用程序以供最终用户下载和执行,则无需发布证书或应用程序中的私钥。私有密钥和关联的证书将存储在只有您可以访问的密钥库中。
应用程序的最终用户将依赖于 Java 运行时中的 SSL 支持,这将使应用程序能够在验证服务器证书后与站点建立 SSL 连接。Java 运行时在信任库中附带了一组缺省 CA 证书,成功建立 SSL 连接的唯一先决条件是由信任库中的某个 CA 颁发服务器的 SSL 证书。StartSSL 的证书不存在于 Java 运行时的信任库中,至少从版本 6 开始,因此:
或者,您可以使用 JVM 启动标志使用自己的信任库初始化应用程序,或者在初始化 SSL 连接之前执行以下代码:-Djavax.net.ssl.trustStore=<path_to_truststore> -Djavax.net.ssl.trustStorePassword=<truststore_password>
System.setProperty("javax.net.ssl.trustStore","<path_to_truststore>");
System.setProperty("javax.net.ssl.trustStorePassword","<truststore_password>");
仅当您的应用程序是并非小程序的 Java SE 应用程序(或对如何指定信任库具有类似限制的应用程序)时,这是一种可行的方法。
阅读Java keytool文档也会有所帮助。
以下方法装入缺省(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"));