我正在尝试创建自己的HTTPS服务器,我有两个代码段:
第一个:
private SSLContext createSSLContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException, NoSuchProviderException {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("c:\\tmp\\clientkeystore.jks"), "123456".toCharArray());
// Create key manager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "123456".toCharArray());
KeyManager[] km = keyManagerFactory.getKeyManagers();
// Create trust manager
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
TrustManager[] tm = trustManagerFactory.getTrustManagers();
// Initialize SSLContext
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(km, tm, null);
return sslContext;
}
第二个:
private SSLContext createSSLContext2() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException, NoSuchProviderException {
String path = "c:/tmp/example.crt2";
byte[] certbytes = Files.readAllBytes(Paths.get(path));
ByteArrayInputStream derInputStream = new ByteArrayInputStream(certbytes);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null, "".toCharArray());
trustStore.setCertificateEntry(alias, cert);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(trustStore, null);
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagers, trustManagers, null);
return sslContext;
}
第一个片段的一切都很好用,但是,我想获得更多 - 我为我的本地域创建了自签名SSL证书并将其保存在外部文件中。当我尝试使用该证书(example.crt2)时,我遇到以下异常:
javax.net.ssl.SSLHandshakeException:没有共同的密码套件 at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) 在sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) 在sun.security.ssl.Handshaker.fatalSE(Handshaker.java:292)
并且curl的完整输出是:
$ curl -k -vvv https://example.org:443 *重建网址:https://example.org:443/ *不支持名称查找超时 *尝试127.0.0.1 ... *连接到example.org(127.0.0.1)端口443(#0) * ALPN,提供http / 1.1 *密码选择:ALL:!导出:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH *成功设置证书验证位置: * CAfile:C:/ Program Files / Git / mingw64 / ssl / certs / ca-bundle.crt CApath:无 * TLSv1.2(OUT),TLS标题,证书状态(22): * TLSv1.2(OUT),TLS握手,客户端问候(1): * TLSv1.2(IN),TLS标题,未知(21): * TLSv1.2(IN),TLS警报,服务器问候(2): *错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:sslv3警报握手失败 *关闭连接0 curl:(35)错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:sslv3警报握手失败
clientkeystore.jks中的证书由以下命令行生成:
keytool -genkey ...
第二个代码段的证书是通过openssl生成的:
$ openssl version -a
OpenSSL 1.0.2e 3 Dec 2015
built on: reproducible build, date unspecified
platform: mingw64
options: bn(64,64) rc4(16x,int) des(idx,cisc,2,long) idea(int) blowfish(idx)
compiler: gcc -I. -I.. -I../include -I/mingw64/include -D_WINDLL -DOPENSSL_PIC -DZLIB_SHARED -DZLIB -DOPENSSL_THREADS -D_MT -DDSO_WIN32 -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/mingw64/ssl"
我做错了什么?请帮助!
答案 0 :(得分:1)
在第二种情况下,没有私钥,只有证书。您需要使用包含私钥条目的TrustStore初始化KeyManager。
无论如何,你所做的事情都没有意义。您不能将同一文件用作KeyStore和信任库。这没有任何意义。