论坛首页 Java企业应用论坛

SSL介绍与Java实例

浏览 62833 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2012-11-19  
正想了解这方面的知识,感谢楼主分享
0 请登录后投票
   发表时间:2012-12-14  
楼主你好,有几个问题请教一下:
1.使用keytool生成了一个keystore,这个keystore里头有三种东西:public key, private key以及certificate,public/private key是用来对交换数据进行加解密,而certificate是用来作verify,这样理解对吗?
2.所谓的“签名”(自签名或第三方机构签名)究竟指的是什么?将certificate加入到keystore这个动作?或是将certificate加入到浏览器的信任列表中?
3.跟smallbee同学一样的问题,浏览器的信任列表保存的究竟是什么?(1)文件,客户端直接在本地对比接收的certificate跟信任列表中的certificate对比来进行判断;(2)地址,客户端会将接收的certificate发送到CA服务器去做验证,然后根据验证结果判断该certificate是否合法(类似于POS机去连接银行的系统验证),答案是哪一个呢?
0 请登录后投票
   发表时间:2012-12-14   最后修改:2012-12-14
Mossad 写道
楼主你好,有几个问题请教一下:
1.使用keytool生成了一个keystore,这个keystore里头有三种东西:public key, private key以及certificate,public/private key是用来对交换数据进行加解密,而certificate是用来作verify,这样理解对吗?


对。

Mossad 写道
2.所谓的“签名”(自签名或第三方机构签名)究竟指的是什么?将certificate加入到keystore这个动作?或是将certificate加入到浏览器的信任列表中?


你需要了解几个概念:

1. 证书
2. 公钥
3. 私钥

证书是用来保存的东西。公钥和私钥是一对钥匙,用来对证书加解密。可以用公钥加密,私钥解密。也可以用公钥解密,私钥加密。因为非对称算法的重点在于“非对称”,既加密和解密不用同一把key。至于你用什么key做加密,什么key解密,它不关心。

对于SSL这个具体的情况,是用private key解密证书,public key加密证书。所以key是用来对证书进行加解密用的。

上面说的是key。key和cert(证书)是相互独立的概念,不要混在一起。

接下来说说证书。证书在最普通的情况下有2个:

1. 服务端证书
2. 对服务端证书签名的第三方机构证书

这是最常见的SSL连接时的情况。比如你连接https://example.com

那么example.com会交给你服务端证书,就是它自己的证书。但是这个证书是它自己生成的,怎么证明它是有效的呢?需要一个独立的第三方机构对它签名,签了名的证书才是有效的。

举个例子:别人过来对你说,我是张三。你肯定不信,觉得他是骗子,于是他出示了身份证,上面写着他是张三。此时你还不能相信,万一身份证有假怎么办?于是你看到他的身份证上面盖着北京市公安局的红印,有公安局的证明,于是你相信了。这里面市公安局就是第三方的权威机构,它对这个身份证做了背书,签了名。于是证明了这个身份证的有效性。

但是你为什么要相信公安局是权威机构呢?也就是说,你为什么认为CA机构(比如VeriSign)签名的机构是权威有效的呢?

这个是就是社会法则的约定了。在你的浏览器,你的JDK环境,你的Linux系统,各个环境中,都有一套默认的CA机构证书保存在里面,你打开Firefox或是IE或者是JDK的默认安装路径,你都能看到默认的200多家CA机构的证书。这些是计算机世界下默认的权威机构,只要是它们签名的证书就是合法有效的。

回到刚才的例子,example.com的证书传给你的ie浏览器,它会检查:1. 证书的CN = example.com,也就是域名和证书的名称一致 2. 证书有第三方机构签名 3. 证书有第三方机构的签名 4. 第三方机构在自己的信任列表当中。

如果满足上面的条件,那么这张证书就是合法有效的,于是建立连接。

在这个过程中,由非对称算法保证整个过程的可靠性,比如密文不会被破解,证书不会在传输过程中被修改等等。

所以证书本身和加密算法是相互独立的。算法是保证传输过程的可靠,而证书的交换过程才是核心的业务流程。

随便提一句,非对称算法非常耗CPU,所以SSL连接过程中,只有交换证书这一过程使用非对称的RSA算法,一旦证书验证完成,客户端信任服务端,那么双方就回退到对称加密算法进行通信,比如DSA等。

因为对称加密算法的密钥在一开始是通过非对称的RSA进行双方的传输的,所以可以保证一开始的key不会被第三方获取,所以保证后续的通信也是有效的。

上面是最简单的情况。有的时候,不光客户端要验证服务端的证书,服务端还要验证客户端的证书。也就是服务端也不相信客户端,需要验证客户端的合法有效性。那么这种情况下,需要几个证书呢?

答案是4个:

1. 服务端证书
2. 对服务端证书签名的第三方机构证书
3. 客户端证书
4. 对客户端证书签名的第三方机构证书

这个你很好理解了。你在银行办网银专业版的时候,银行会给你一个key。这个key就是你的个人证书了,银行负责对给你的证书签名,签名有笔费用,大概是几十块的样子。

你回到家用网银专业版的时候,就要使用你的个人证书,否则银行不会信任你的客户端,也不允许你连接。

Mossad 写道
3.跟smallbee同学一样的问题,浏览器的信任列表保存的究竟是什么?(1)文件,客户端直接在本地对比接收的certificate跟信任列表中的certificate对比来进行判断;(2)地址,客户端会将接收的certificate发送到CA服务器去做验证,然后根据验证结果判断该certificate是否合法(类似于POS机去连接银行的系统验证),答案是哪一个呢?


浏览器的证书管理程序里面都可以保存什么?这个问题相信你自己已经可以回答了。

下面是Firefox里面的界面:



首先是你的个人证书,你自己的身份证,会员卡,等等。你的身份证如果不是公安局(第三方权威机构签名的),那么就得是对方签名的(去什么健身会所,就出示那个会所的会员卡,否则人家不认)






别的个人和机构的证书,这是你信任的人和机构。访问它们的https://网站的时候,会自动信任他们。



CA证书,这个很厉害了。这些是公安局和各机构的证书,你不但信任他们本身,只要是这些人签名的任何证书,你都信。,
  • 大小: 72 KB
  • 大小: 44.2 KB
  • 大小: 72.2 KB
  • 大小: 66.6 KB
0 请登录后投票
   发表时间:2012-12-25  
楼主太专业了,膜拜!
学习!
0 请登录后投票
   发表时间:2013-03-14  
“服务端证书里面的CN一定和服务端的域名统一,我们的证书服务的域名是localhost,那么我们的客户端在连接服务端时一定也要用localhost来连接,否则根据SSL协议标准,域名与证书的CN不匹配,说明这个证书是不安全的,通信将无法正常运行”
我实验了一下,在SSLClient创建socket的时候,Socket s = sf.createSocket("localhost", 8443);  将“localhost”改为“127.0.0.1”以及我主机的外部IP,输出的日志都一样,看不出异常。
想请教您,这是什么原因?我如何才能抓到这个异常?
0 请登录后投票
   发表时间:2013-03-14  
CQUZL 写道
“服务端证书里面的CN一定和服务端的域名统一,我们的证书服务的域名是localhost,那么我们的客户端在连接服务端时一定也要用localhost来连接,否则根据SSL协议标准,域名与证书的CN不匹配,说明这个证书是不安全的,通信将无法正常运行”
我实验了一下,在SSLClient创建socket的时候,Socket s = sf.createSocket("localhost", 8443);  将“localhost”改为“127.0.0.1”以及我主机的外部IP,输出的日志都一样,看不出异常。
想请教您,这是什么原因?我如何才能抓到这个异常?

为何要用localhost或者127.0.0.1呢 一般都是一个内网IP或者公网IP,否则别人也无法连你服务器。
0 请登录后投票
   发表时间:2013-03-14  
smallbee 写道
CQUZL 写道
“服务端证书里面的CN一定和服务端的域名统一,我们的证书服务的域名是localhost,那么我们的客户端在连接服务端时一定也要用localhost来连接,否则根据SSL协议标准,域名与证书的CN不匹配,说明这个证书是不安全的,通信将无法正常运行”
我实验了一下,在SSLClient创建socket的时候,Socket s = sf.createSocket("localhost", 8443);  将“localhost”改为“127.0.0.1”以及我主机的外部IP,输出的日志都一样,看不出异常。
想请教您,这是什么原因?我如何才能抓到这个异常?

为何要用localhost或者127.0.0.1呢 一般都是一个内网IP或者公网IP,否则别人也无法连你服务器。

我是想测试域名和证书CN中的信息不匹配,会报什么异常。
我的测试用例:
1.用IP访问(127.0.0.1和我机器的外部IP),证书CN信息是localhost
2.用域名访问localhost,证书CN信息是test.server.com
但是均没有报出异常,那就意味着,建立SSL连接的时间,没有去验证,我们访问的域名和证书中的CN是否匹配

0 请登录后投票
   发表时间:2013-03-14  
我看了您说的用HostnameVerifier()去验证urlHostName和SSLSession session,那如果不用这个方法,SSL默认就不验证了,是吗?
0 请登录后投票
   发表时间:2013-03-14  
suipy 写道
我看了您说的用HostnameVerifier()去验证urlHostName和SSLSession session,那如果不用这个方法,SSL默认就不验证了,是吗?



suipy 写道
另外,最重要的一点,服务端证书里面的CN一定和服务端的域名统一,我们的证书服务的域名是localhost,那么我们的客户端在连接服务端时一定也要用localhost来连接,否则根据SSL协议标准,域名与证书的CN不匹配,说明这个证书是不安全的,通信将无法正常运行
此次加入以下代码也可以解决:
System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
     HostnameVerifier hv = new HostnameVerifier() {
          public boolean verify(String urlHostName, SSLSession session) {
           return urlHostName.equals(session.getPeerHost());
          }
     };
   
     HttpsURLConnection.setDefaultHostnameVerifier(hv);
0 请登录后投票
论坛首页 Java企业应用版

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