论坛首页 Java企业应用论坛

数字认证的迷惑

浏览 32940 次
精华帖 (0) :: 良好帖 (7) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-17  
ximencf 写道
呵呵,多谢grandboy和daquan198163。问题基本搞定@

发个总结的贴吧。
0 请登录后投票
   发表时间:2009-08-18   最后修改:2009-08-18
我觉得这个方案虽然能跑,但是基本无法满足实际需要:
首先,客户证书不应该存储在证书库文件,而应该是数据库,以便管理和使用。
第二,现在这种方案是完全依赖应用服务器的能力来做客户认证,这样不仅绑定服务器,而且无法满足应用程序对认证的需求。我猜测这个机制只是保证了合法的用户可以建立https连接,至于https请求进来以后,应用系统还是无法获得用户身份,也就无法做登录认证。
所以我觉得好用的证书认证方案必须要定制,不过也不一定是从零开始,Acegi也就是现在的SpringSecurity提供了一种X509证书登陆的机制,应该就是做这个的。
0 请登录后投票
   发表时间:2009-08-18  
daquan198163 写道
我觉得这个方案虽然能跑,但是基本无法满足实际需要:
首先,客户证书不应该存储在证书库文件,而应该是数据库,以便管理和使用。
第二,现在这种方案是完全依赖应用服务器的能力来做客户认证,这样不仅绑定服务器,而且无法满足应用程序对认证的需求。我猜测这个机制只是保证了合法的用户可以建立https连接,至于https请求进来以后,应用系统还是无法获得用户身份,也就无法做登录认证。
所以我觉得好用的证书认证方案必须要定制,不过也不一定是从零开始,Acegi也就是现在的SpringSecurity提供了一种X509证书登陆的机制,应该就是做这个的。


如果是真正的CA的话,一定是要有数据库或者LDAP来做支撑的。因为有SSL标准,大家都按照这个标准来的,其实这就是证书认证的方式。服务器可能实现各有差别的,但是和浏览器通讯都是按照标准来做的,所以不存在绑定服务器的问题。至于用户身份的问题,就是你怎么把客户证书映射到系统用户的问题。服务器能取到证书了,这个应该就不难了。Acegi没用过。
0 请登录后投票
   发表时间:2009-08-18  
我的意思是SSL双向认证中的客户认证这一块,没有实际意义,所以一般都默认采用单向认证。
SSL当然还是靠服务器本身提供。
0 请登录后投票
   发表时间:2009-08-18  
总结的贴,等我这个小东西做完的时候,一起发出来。最近才接触这个,所以认识不是很深刻。但是就如grandboy 所说,上述的所有做法,满足的是一个基于双向的SSL的有效性的校验,至于提醒用户延长证书有效期,或者用户仅凭证书就能登陆等问题,只要客户端能取得到了安装证书的信息,那么这些逻辑判断就不是难事。
0 请登录后投票
   发表时间:2009-08-20   最后修改:2009-08-20
期待lz的总结
我也遇到了问题,如下:
我的配置:
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
secure="true" scheme="https" port="9443" 
SSLEnabled="true" maxHttpHeaderSize="8192" maxThreads="150" 
minSpareThreads="25" maxSpareThreads="75" enableLookups="false" 
disableUploadTimeout="true" acceptCount="100" sslProtocol="TLS" 
clientAuth="true" 
keystoreFile="cert/server.p12" keystoreType="PKCS12" keystorePass="123456"
truststoreFile="cert/root.jks"   truststoreType="JKS" truststorePass="123456"/>


    public MyX509TrustManager() { 
        try {
			keyStore = KeyStore.getInstance("JKS"); 
			keyStore.load(new ClassPathResource("root.jks").getInputStream(),"123456".toCharArray());
			
			TrustManagerFactory tmf = 
			TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			tmf.init(keyStore); 

			TrustManager tms [] = tmf.getTrustManagers(); 
			for (int i = 0; i < tms.length; i++) { 
			    if (tms[i] instanceof X509TrustManager) { 
			        jSSEX509TrustManager = (X509TrustManager) tms[i]; 
			        return; 
			    } 
			}
		} catch (Exception e) {
			System.out.println(e);
		}


	static SSLSocketFactory ssf = null;
	static {
		try {
			final TrustManager[] tm = { myX509TrustManager };
			final SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, tm, new java.security.SecureRandom());

			// 从上述SSLContext对象中得到SSLSocketFactory对象
			ssf = sslContext.getSocketFactory();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

		try {
final HttpsURLConnection httpsConn = (HttpsURLConnection) validationUrl.openConnection();
			httpsConn.setSSLSocketFactory(ssf);
			in = new BufferedReader(new InputStreamReader(httpsConn.getInputStream()));


在in = new BufferedReader(new InputStreamReader(httpsConn.getInputStream()));
这里的时候报错
<javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate>
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1682)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)

还望指教
0 请登录后投票
   发表时间:2009-08-20   最后修改:2009-08-20
问题儿童 写道
期待lz的总结
我也遇到了问题,如下:
我的配置:
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
secure="true" scheme="https" port="9443" 
SSLEnabled="true" maxHttpHeaderSize="8192" maxThreads="150" 
minSpareThreads="25" maxSpareThreads="75" enableLookups="false" 
disableUploadTimeout="true" acceptCount="100" sslProtocol="TLS" 
clientAuth="true" 
keystoreFile="cert/server.p12" keystoreType="PKCS12" keystorePass="123456"
truststoreFile="cert/root.jks"   truststoreType="JKS" truststorePass="123456"/>


    public MyX509TrustManager() { 
        try {
			keyStore = KeyStore.getInstance("JKS"); 
			keyStore.load(new ClassPathResource("root.jks").getInputStream(),"123456".toCharArray());
			
			TrustManagerFactory tmf = 
			TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			tmf.init(keyStore); 

			TrustManager tms [] = tmf.getTrustManagers(); 
			for (int i = 0; i < tms.length; i++) { 
			    if (tms[i] instanceof X509TrustManager) { 
			        jSSEX509TrustManager = (X509TrustManager) tms[i]; 
			        return; 
			    } 
			}
		} catch (Exception e) {
			System.out.println(e);
		}


	static SSLSocketFactory ssf = null;
	static {
		try {
			final TrustManager[] tm = { myX509TrustManager };
			final SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, tm, new java.security.SecureRandom());

			// 从上述SSLContext对象中得到SSLSocketFactory对象
			ssf = sslContext.getSocketFactory();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

		try {
final HttpsURLConnection httpsConn = (HttpsURLConnection) validationUrl.openConnection();
			httpsConn.setSSLSocketFactory(ssf);
			in = new BufferedReader(new InputStreamReader(httpsConn.getInputStream()));


在in = new BufferedReader(new InputStreamReader(httpsConn.getInputStream()));
这里的时候报错
<javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate>
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1682)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)

还望指教


请参考一下: http://grandboy.iteye.com/admin/blogs/451768 里面有些在这个帖子里已经提到了,有些没有提到的。没提到的,你自己按照上面的检查一下。另外,提醒你一定注意哪个是SSL的客户端,哪个服务器。如果搞不清楚这个,通常会出一些错误。

希望对你有帮助。
0 请登录后投票
   发表时间:2009-08-22   最后修改:2009-08-22
问题儿童 写道
期待lz的总结
我也遇到了问题,如下:
我的配置:
.......
请参考一下: http://grandboy.iteye.com/admin/blogs/451768 里面有些在这个帖子里已经提到了,有些没有提到的。没提到的,你自己按照上面的检查一下。另外,提醒你一定注意哪个是SSL的客户端,哪个服务器。如果搞不清楚这个,通常会出一些错误。

希望对你有帮助。

hi,grandboy
补充下,我的应用都是在同一个tomcat下
我做了尝试,
openssl x509 -in root-cert.pem -outform DER -out server-cert.cer
keytool -import -keystore root.jks -alias rs -file server-cert.cer -storepass 123456
显然报 了一个路径错误,但我tomcat启动初始化时并无错误,只是在ssl握手的时候错了
难道不是
keystoreFile="cert/server.p12" keystoreType="PKCS12" keystorePass="123456"
truststoreFile="cert/root.jks"   truststoreType="JKS" truststorePass="123456"/>
我在server。xml里面指定的吗?


<javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target>
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
0 请登录后投票
   发表时间:2009-08-23  
keytool -import -v -trustcacerts -storepass 123456 -alias rs -file server-cert.pem -keystore root.jks
同时,我不知道你的server是不是也是root签名的还是怎么的?
请参看http://www.iteye.com/topic/120780,这是一个完整的过程。
希望成功,共同学习。
0 请登录后投票
   发表时间:2009-08-24  
问题在这里
		SSLContext.init(KeyManagerFactory.getKeyManagers(), TrustManagerFactory.getTrustManagers(), null);

init的两个参数一定要有
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics