次のメソッドは、デフォルト(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"));
証明書をインポートせずに動作する場合は、セキュリティがどのように確保されるかはわかりません。 Webサイト証明書をインポートします。 JavaがStartSSLを有効な認証局として認識できなかったため、証明書をインポートする必要がある場合はStartSSLのルート証明書で、Webサイト証明書はインポートできません。 –
@JBああ。以前の質問では、虚偽のサービスに話していることを確認するためにクライアントのサーバの証明書を検証し、keytoolについて何か言及しておく必要があるとChubbardが言ったからです。だから、ウェブサイトの証明書をインポートしてもセキュリティに影響を与えないと言ったら、誰がSSL証明書をインポートするのですか? – Andy
ブラウザと同じように、Webサイトの証明書を検証するJavaのSSLスタックです。あなたが訪問したすべてのSSLウェブサイトの証明書をインポートしますか?いいえ。ブラウザは、ブラウザが認識している既知の認証局によって認証されているため、証明書を検証します。 StartSSLは、あなたの場合の認証局です。 Javaも同じことをします。 StartSSLの証明書はインポートする必要がありますが、Webサイトの証明書はインポートする必要があります。 –