锁定老帖子 主题:数字认证的迷惑
精华帖 (0) :: 良好帖 (7) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-17
ximencf 写道 呵呵,多谢grandboy和daquan198163。问题基本搞定@
发个总结的贴吧。 |
|
返回顶楼 | |
发表时间:2009-08-18
最后修改:2009-08-18
我觉得这个方案虽然能跑,但是基本无法满足实际需要:
首先,客户证书不应该存储在证书库文件,而应该是数据库,以便管理和使用。 第二,现在这种方案是完全依赖应用服务器的能力来做客户认证,这样不仅绑定服务器,而且无法满足应用程序对认证的需求。我猜测这个机制只是保证了合法的用户可以建立https连接,至于https请求进来以后,应用系统还是无法获得用户身份,也就无法做登录认证。 所以我觉得好用的证书认证方案必须要定制,不过也不一定是从零开始,Acegi也就是现在的SpringSecurity提供了一种X509证书登陆的机制,应该就是做这个的。 |
|
返回顶楼 | |
发表时间:2009-08-18
daquan198163 写道 我觉得这个方案虽然能跑,但是基本无法满足实际需要:
首先,客户证书不应该存储在证书库文件,而应该是数据库,以便管理和使用。 第二,现在这种方案是完全依赖应用服务器的能力来做客户认证,这样不仅绑定服务器,而且无法满足应用程序对认证的需求。我猜测这个机制只是保证了合法的用户可以建立https连接,至于https请求进来以后,应用系统还是无法获得用户身份,也就无法做登录认证。 所以我觉得好用的证书认证方案必须要定制,不过也不一定是从零开始,Acegi也就是现在的SpringSecurity提供了一种X509证书登陆的机制,应该就是做这个的。 如果是真正的CA的话,一定是要有数据库或者LDAP来做支撑的。因为有SSL标准,大家都按照这个标准来的,其实这就是证书认证的方式。服务器可能实现各有差别的,但是和浏览器通讯都是按照标准来做的,所以不存在绑定服务器的问题。至于用户身份的问题,就是你怎么把客户证书映射到系统用户的问题。服务器能取到证书了,这个应该就不难了。Acegi没用过。 |
|
返回顶楼 | |
发表时间:2009-08-18
我的意思是SSL双向认证中的客户认证这一块,没有实际意义,所以一般都默认采用单向认证。
SSL当然还是靠服务器本身提供。 |
|
返回顶楼 | |
发表时间:2009-08-18
总结的贴,等我这个小东西做完的时候,一起发出来。最近才接触这个,所以认识不是很深刻。但是就如grandboy 所说,上述的所有做法,满足的是一个基于双向的SSL的有效性的校验,至于提醒用户延长证书有效期,或者用户仅凭证书就能登陆等问题,只要客户端能取得到了安装证书的信息,那么这些逻辑判断就不是难事。
|
|
返回顶楼 | |
发表时间: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) 还望指教 |
|
返回顶楼 | |
发表时间: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的客户端,哪个服务器。如果搞不清楚这个,通常会出一些错误。 希望对你有帮助。 |
|
返回顶楼 | |
发表时间: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) |
|
返回顶楼 | |
发表时间: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,这是一个完整的过程。 希望成功,共同学习。 |
|
返回顶楼 | |
发表时间:2009-08-24
问题在这里
SSLContext.init(KeyManagerFactory.getKeyManagers(), TrustManagerFactory.getTrustManagers(), null); init的两个参数一定要有 |
|
返回顶楼 | |