锁定老帖子 主题:SSL介绍与Java实例
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2012-11-19
正想了解这方面的知识,感谢楼主分享
|
|
返回顶楼 | |
发表时间: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机去连接银行的系统验证),答案是哪一个呢? |
|
返回顶楼 | |
发表时间: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证书,这个很厉害了。这些是公安局和各机构的证书,你不但信任他们本身,只要是这些人签名的任何证书,你都信。, |
|
返回顶楼 | |
发表时间:2012-12-25
楼主太专业了,膜拜!
学习! |
|
返回顶楼 | |
发表时间:2013-03-14
“服务端证书里面的CN一定和服务端的域名统一,我们的证书服务的域名是localhost,那么我们的客户端在连接服务端时一定也要用localhost来连接,否则根据SSL协议标准,域名与证书的CN不匹配,说明这个证书是不安全的,通信将无法正常运行”
我实验了一下,在SSLClient创建socket的时候,Socket s = sf.createSocket("localhost", 8443); 将“localhost”改为“127.0.0.1”以及我主机的外部IP,输出的日志都一样,看不出异常。 想请教您,这是什么原因?我如何才能抓到这个异常? |
|
返回顶楼 | |
发表时间: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,否则别人也无法连你服务器。 |
|
返回顶楼 | |
发表时间: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是否匹配 |
|
返回顶楼 | |
发表时间:2013-03-14
我看了您说的用HostnameVerifier()去验证urlHostName和SSLSession session,那如果不用这个方法,SSL默认就不验证了,是吗?
|
|
返回顶楼 | |
发表时间: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); |
|
返回顶楼 | |