我正在尝试将comodo Positive SSL多站点证书加载到Java的HttpsServer中。我没有从代码中获得任何错误,但是当我尝试在浏览器中访问URL时,它告诉我存在SSL错误。 Chrome和FireFox都不提供任何其他信息。这个证书在Apache中运行良好。
以下是我正在使用的代码。我把它弄得相当冗长。有什么突出的不正确吗?我已将私钥转换为pkcs8进行导入。我正在加载的证书和软件包是PEM编码的。
serverHttps = HttpsServer.create(new InetSocketAddress(ports[port_selector]), 0);
SSLContext sslContext = SSLContext.getInstance("TLS");
String alias = "alias";
// Load Certificates
InputStream stream = MyClass.class.getResourceAsStream("/certs/mycert.crt");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(stream);
stream.close();
stream = MyClass.class.getResourceAsStream("/certs/bundle.crt");
cf = CertificateFactory.getInstance("X.509");
Collection bundle = cf.generateCertificates(stream);
stream.close();
// Build cert chain
java.security.cert.Certificate[] chain = new Certificate[bundle.size()+1];
Iterator i = bundle.iterator();
int pos = 0;
while (i.hasNext()) {
chain[pos] = (Certificate)i.next();
pos++;
}
chain[chain.length-1] = cert;
// Load private key
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
stream = MyClass.class.getResourceAsStream("/certs/pkcs8_my_key");
PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(IOUtils.toByteArray(stream));
RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8);
stream.close();
stream = null;
KeyStore ks = KeyStore.getInstance("JKS");
char[] ksPassword = "mypass".toCharArray();
ks.load(null, ksPassword);
ks.setKeyEntry(alias, privKey, ksPassword, chain);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ksPassword);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
// serverHttps.setHttpsConfigurator(new HttpsConfigurator(sslContext));
serverHttps.setHttpsConfigurator ( new HttpsConfigurator( sslContext )
{
@Override
public void configure ( HttpsParameters params )
{
try
{
// initialise the SSL context
SSLContext c = SSLContext.getDefault ();
SSLEngine engine = c.createSSLEngine ();
params.setNeedClientAuth ( false );
params.setCipherSuites ( engine.getEnabledCipherSuites () );
params.setProtocols ( engine.getEnabledProtocols () );
// get the default parameters
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters ();
params.setSSLParameters ( defaultSSLParameters );
}
catch ( Exception ex )
{
System.out.println( "Failed to configure HTTPS server: "+ex.getMessage() );
System.exit(100);
}
}
} );
答案 0 :(得分:1)
您的服务器证书必须是密钥库条目中的chain[0]
。
其余的证书应该处于向上的顺序,即根最后 - 当你使用keytool时,它按顺序放置 - 因为JSSE服务器以密钥库顺序和SSL / TLS协议发送它们说他们应该按顺序发送。但是,根据我的经验(大多数?),只要服务器证书是第一个,浏览器/客户端就会容忍链的其余部分出现故障。
PS:我认为 configure
覆盖中的所有内容都是不必要的。您没有做任何事情来使SSLContext的参数与默认参数不同,默认上下文的SSLParameters是(并覆盖)您刚刚单独设置的CipherSuites和Protocols。但我不能轻易测试。