本文介绍在Tomcat中配置HTTPS双向认证(验证客户端)的情况下,如何验证CRL。
我们可以按照文章 《如何用Tomcat和Openssl构建HTTPS双向认证环境(HTTPS客户端认证)》( http://blog.csdn.net/jasonhwang/archive/2008/04/29/2344768.aspx)里的方法在Tomcat里构建一个HTTPS验证客户端证书(Usbkey或文件数字证书)的环境。但是这样配置后,Tomcat只会根据CA的证书来验证客户端证书是否合法(是否是CA签过名的),但是没有检查该客户端证书是否已经被吊销。所以必须进一步检查CRL(Certification Revocation List)即证书吊销列表。
CRL它记录了CA吊销的未过期的证书(可能是因为用户的私钥被泄露了等原因)。好像Tomcat 5.5.17版本在HTTPS的<Connector>配置里加了一个crlFile选项,来指向一个CRL文件。但是个人认为这种方式不好,因为若Tomcat在底层帮你完成了CRL的检查,并直接拒绝了客户端(浏览器)的请求,你的应用程序(webapp)并不知道,这样的坏处是:
(1)用户在被拒绝时可能得到一个不友好的错误提示页面(当然和你的页面风格完全不同)。
(2)当然你也无法引导用户进入另一个帮助页面。
(3)应用层无法记录这种非法的访问。
所以我建议我们还是通过java.security.cert.X509CRL这个Java类库自带的类来由应用程序自己判断。而且这个工作也非常简单:
(1)获取CRL文件:
一般CA会在其网站上定时发布CRL文件(标准的X509格式),我们可以定期下载(用HTTP/FTP)到我们的Web服务器。当然这个过程既可以人工完成也可以写一个程序周期去取。
(2)在Tomcat的应用里装在CRL:
你可以定时重读一下CRL文件(或每次下载后出发重读一下CRL文件),装在CRL文件到X509CRL对象方法如下:
注:简单期间本文不对Exception进行处理。
(3)检查客户端证书是否被吊销:
当HTTPS验证客户端成功后,进入我们的webapp时(servlet/jsp),我们可以从请求中得到用户的证书:
注:可以参考
《如何用Tomcat和Openssl构建HTTPS双向认证环境(HTTPS客户端认证)》里的那个显示客户端证书的jsp。
接下来验证证书是否被吊销的方法非常简单,只要把客户证书传入X509CRL的isRevoked函数就行:
如果返回true,就说明该证书已被吊销,你就可以引导客户端浏览器进入显示错误提示的页面。
测试方法:你可以参考 《利用openssl创建一个简单的CA》( http://blog.csdn.net/jasonhwang/archive/2008/04/26/2329589.aspx)里的方法,自己生成客户端证书,然后吊销证书并生成CRL文件来进行测试。
我们可以按照文章 《如何用Tomcat和Openssl构建HTTPS双向认证环境(HTTPS客户端认证)》( http://blog.csdn.net/jasonhwang/archive/2008/04/29/2344768.aspx)里的方法在Tomcat里构建一个HTTPS验证客户端证书(Usbkey或文件数字证书)的环境。但是这样配置后,Tomcat只会根据CA的证书来验证客户端证书是否合法(是否是CA签过名的),但是没有检查该客户端证书是否已经被吊销。所以必须进一步检查CRL(Certification Revocation List)即证书吊销列表。
CRL它记录了CA吊销的未过期的证书(可能是因为用户的私钥被泄露了等原因)。好像Tomcat 5.5.17版本在HTTPS的<Connector>配置里加了一个crlFile选项,来指向一个CRL文件。但是个人认为这种方式不好,因为若Tomcat在底层帮你完成了CRL的检查,并直接拒绝了客户端(浏览器)的请求,你的应用程序(webapp)并不知道,这样的坏处是:
(1)用户在被拒绝时可能得到一个不友好的错误提示页面(当然和你的页面风格完全不同)。
(2)当然你也无法引导用户进入另一个帮助页面。
(3)应用层无法记录这种非法的访问。
所以我建议我们还是通过java.security.cert.X509CRL这个Java类库自带的类来由应用程序自己判断。而且这个工作也非常简单:
(1)获取CRL文件:
一般CA会在其网站上定时发布CRL文件(标准的X509格式),我们可以定期下载(用HTTP/FTP)到我们的Web服务器。当然这个过程既可以人工完成也可以写一个程序周期去取。
(2)在Tomcat的应用里装在CRL:
你可以定时重读一下CRL文件(或每次下载后出发重读一下CRL文件),装在CRL文件到X509CRL对象方法如下:
import
java.security.cert.
*
;
public X509CRL loadX509CRL(String crlFilePath) {
InputStream inStream = new FileInputStream(crlFilePath);
CertificateFactory cf = CertificateFactory.getInstance( " X.509 " );
X509CRL crl = (X509CRL)cf.generateCRL(inStream);
inStream.close();
return crl;
}
public X509CRL loadX509CRL(String crlFilePath) {
InputStream inStream = new FileInputStream(crlFilePath);
CertificateFactory cf = CertificateFactory.getInstance( " X.509 " );
X509CRL crl = (X509CRL)cf.generateCRL(inStream);
inStream.close();
return crl;
}
(3)检查客户端证书是否被吊销:
当HTTPS验证客户端成功后,进入我们的webapp时(servlet/jsp),我们可以从请求中得到用户的证书:
java.security.cert.X509Certificate cert
=
null
;
java.security.cert.X509Certificate[] certs = null ;
certs = (X509Certificate[])request.getAttribute( " javax.servlet.request.X509Certificate " );
if (certs.length > 0 ) {
cert = certs[ 0 ];
}
java.security.cert.X509Certificate[] certs = null ;
certs = (X509Certificate[])request.getAttribute( " javax.servlet.request.X509Certificate " );
if (certs.length > 0 ) {
cert = certs[ 0 ];
}
接下来验证证书是否被吊销的方法非常简单,只要把客户证书传入X509CRL的isRevoked函数就行:
boolean
result
=
crl.isRevoked(cert);
测试方法:你可以参考 《利用openssl创建一个简单的CA》( http://blog.csdn.net/jasonhwang/archive/2008/04/26/2329589.aspx)里的方法,自己生成客户端证书,然后吊销证书并生成CRL文件来进行测试。