使用带有Java HttpsServer的正SSL多站点证书时出现问题

时间:2015-09-03 02:14:33

标签: java web-services ssl

我正在尝试将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);
        }
    }
} );

1 个答案:

答案 0 :(得分:1)

您的服务器证书必须是密钥库条目中的chain[0]

其余的证书应该处于向上的顺序,即根最后 - 当你使用keytool时,它按顺序放置 - 因为JSSE服务器以密钥库顺序和SSL / TLS协议发送它们说他们应该按顺序发送。但是,根据我的经验(大多数?),只要服务器证书是第一个,浏览器/客户端就会容忍链的其余部分出现故障。

PS:我认为 configure覆盖中的所有内容都是不必要的。您没有做任何事情来使SSLContext的参数与默认参数不同,默认上下文的SSLParameters是(并覆盖)您刚刚单独设置的CipherSuites和Protocols。但我不能轻易测试。