StartSSL证书使用相关问题
最近申请了startssl的多个https证书,碰到一系列问题,逐个备忘一下。
1、nginx对同一个IP上多个域名证书的支持,下面的:TLS SNI support enabled。
[code]
#./nginx -V
nginx version: nginx/1.x.x
built by gcc 4.x.x 201xxxxx (Red Hat 4.x.x-x) (GCC)
TLS SNI support enabled
[/code]
如果不支持,需要重新编译openssl及nginx。
2、wget认证不过及firefox认证失败的问题。
[code]
ERROR: cannot verify www.xxxx.com's certificate, issued by `/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA':
Unable to locally verify the issuer's authority.
[/code]
某些浏览器或wget等工具没有内置StartCom Class 1 Primary Intermediate Server CA的证书为中级认证机构,认证链不完整,所以认证失败。
base64编码的cer,只需要把它的public的cer文件放到自己站点的public的cer下面即可。网上有人直接>>操作,导致中间没有换行,证书不认了,加个换行就对了。
加上它以后,它是被StartCom的根认证机构认证的,论证链就完整了。
3、apcache的Java的DefaultHttpClient,碰到nginx上配置多个证书时,访问其它域名的时候会出错。
[code]
javax.net.ssl.SSLException: hostname in certificate didn't match: <test.api.xxx.com> != <www.xxx.com> OR <xxx.com> OR <www.xxx.com>
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:228)
at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:149)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:130)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:641)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:480)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
[/code]
跟了一下代码,AbstractVerifier.verify中得到的确实是默认的www.xxx.com的证书链,第一个是当前站点,第二个是问题2中加的中级证机构的public证书。
再往下没跟动,怀疑httpclient是用ip得到的证书,也就意味着它不支持同一个IP多个域名证书。解决方案就是实现X509HostnameVerifier以取消域名的验证。
[code]
final X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
@Override
public boolean verify(String host, SSLSession ssl) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {//实际上只会调用这个。
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
};
final SSLSocketFactory ssf = new SSLSocketFactory(ctx, hostnameVerifier);
[/code]