sslsocket通信中的一些问题(JAVA)

来源:互联网 发布:淘宝保证金只退了23元 编辑:程序博客网 时间:2024/06/08 17:41

注:以下内容为学习sslsocket是网上查看资料收集整合结果。感谢原文档作者。

Ssl传输

1.基本介绍

SSL(Secure Socket Layer)安全套接层, 是为网络通信提供安全以及数据完整性的一种安全协议,在传输层对网络连接进行加密

SSL协议分为两层:

1)SSL记录协议,它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。

2)SSL握手协议,它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份验证、协商加密算法、交换加密密钥

SSL的核心是 公开密钥加密,这是种非对称密钥加密,其实直接地说就client和server各自生成一对加密密钥和解密密钥,各自吧加密密钥发给对方,这个是公开的私钥,解密方法保留在本地,加密方法传到对方那里

SSL(SecureSockets Layer 安全套接层),及其继任者传输层安全(TransportLayer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。

  安全证书既包含了用于加密数据的密钥,又包含了用于证实身份的数字签名。安全证书采用公钥加密技术。公钥加密是指使用一对非对称的密钥进行加密或解密。每一对密钥由公钥和私钥组成。公钥被广泛发布。私钥是隐秘的,不公开。用公钥加密的数据只能够被私钥解密。反过来,使用私钥加密的数据只能被公钥解密。这个非对称的特性使得公钥加密很有用。在安全证书中包含着一对非对称的密钥。只有安全证书的所有者才知道私钥。当通信方A将自己的安全证书发送给通信方B时,实际上发给通信方B的是公开密钥,接着通信方B可以向通信方A发送用公钥加密的数据,只有通信方A才能使用私钥对数据进行解密,从而获得通信方B发送的原始数据。安全证书中的数字签名部分是通信方A的电子身份证。数字签名告诉通信方B该信息确实由通信方A发出,不是伪造的,也没有被篡改。

    认证分为双向认证和单向认证。

单向认证只要求站点部署了ssl证书就行,任何用户都可以去访问(IP被限制除外等),只是服务端提供了身份认证。而双向认证则是需要是服务端需要客户端提供身份认证,只能是服务端允许的客户能去访问,安全性相对于要高一些
     
双向认证SSL协议的具体通讯过程,这种情况要求服务器和客户端双方都有证书。单向认证SSL协议不需要客户端拥有CA证书,以及在协商对称密码方案,对称通话密钥时,服务器发送给客户端的是没有加过密的(这并不影响SSL过程的安全性)密码方案。这样,双方具体的通讯内容,就是加密过的数据。如果有第三方攻击,获得的只是加密的数据,第三方要获得有用的信息,就需要对加密的数据进行解密,这时候的安全就依赖于密码方案的安全。而幸运的是,目前所用的密码方案,只要通讯密钥长度足够的长,就足够的安全。这也是我们强调要求使用128位加密通讯的原因。
     
一般Web应用都是采用单向认证的,原因很简单,用户数目广泛,且无需做在通讯层做用户身份验证,一般都在应用逻辑层来保证用户的合法登入。但如果是企业应用对接,情况就不一样,可能会要求对客户端(相对而言)做身份验证。这时就需要做双向认证。

 

2.双向认证模拟场景
Server端和Client端通信,需要进行授权和身份的验证,即Client只能接受Server的消息,Server只能接受Client的消息。
实现技术:
JSSE(Java Security Socket Extension)
是Sun为了解决在Internet上的安全通讯而推出的解决方案。它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,开发人员可以在客户机和服务器之间通过TCP/IP协议安全地传输数据
为了实现消息认证。

Server需要:
1)KeyStore: 其中保存服务端的私钥
2)Trust KeyStore:其中保存客户端的授权证书
同样,Client需要:
1)KeyStore:其中保存客户端的私钥
2)Trust KeyStore:其中保存服务端的授权证书(服务端公钥)

3.常用配置

JAVA开发中通常需要使用以下3个方法:

1. abstract  void  setNeedClientAuth(boolean need)  

2.     控制接受的服务器模式SSLSocket是否将在开始时配置为要求客户端验证。  

3. abstract  void  setUseClientMode(boolean mode)  

4.     控制接受的连接是以(默认的)SSL 服务器模式还是在 SSL 客户端模式工作。  

5. abstract  void  setWantClientAuth(boolean want)  

6.     控制 accept 服务器模式的 SSLSockets 是否将在开始时配置为请求 客户端验证。 

通信端无需向对方证明自己的身份,则称该端处于客户模式,否则称其处于服务器模式,无论是客户端还是服务器端,都可处于客户模式或者服务器模式,但是对于通信双方来说,只能有一方处于服务模式,而另一方则必须处于客户模式默认为客户模式。

  java中是通过SSL认证,使用的是SSLSocket,通过SSLSocketFactory可以获得SSLSocket实例对象。通常SSLSocketFactory需要一个SSLContext环境对象来构建,

构建一个SSLContext环境:

SSLContextsslc=SSLContext.getInstance("SSLv3");
 //
构造SSL环境,指定SSL版本为3.0,也可以使用TLSv1,但是SSLv3更加常用。

 

sslc.init(KeyManager[],TrustManager[]null);
//KeyManager[]
第一个参数是授权的密钥管理器,用来授权验证。TrustManager[]第二个是被授权的证书管理器,用来验证服务器端的证书。第三个参数是一个随机数值,可以填写null。如果只是服务器传输数据给客户端来验证,就传入第一个参数就可以,客户端构建环境就传入第二个参数。

双向认证的话,就同时使用两个管理器。也可以选择使用单向认证,这种情况下client侧不需要提供证书。所以,

server侧只需要自己的keystore文件,不需要truststore文件
client侧不需要自己的keystore文件,只需要truststore文件(其中包含server的公钥)。
此外server侧需要在创建SSLServerSocket之后设定不需要客户端证书:setNeedClientAuth(false)

4.证书:

一个证书是一个实体的数字签名,还包含这个实体的公共钥匙值.
       
公共钥匙 :是一个详细的实体的数字关联,并有意让所有想同这个实体发生信任关系的其他实体知道.公共钥匙用来检验签名;
       
数字签名:是实体信息用实体的私有钥匙签名(加密)后的数据.这条数据可以用这个实体的公共钥匙来检验签名(解密)出实体信息以鉴别实体的身份;       
       
签名:用实体私有钥匙加密某些消息,从而得到加密数据;
       
私有钥匙:是一些数字,私有和公共钥匙存在所有用公共钥匙加密的系统的钥匙对中.公共钥匙用来加密数据,私有钥匙用来计算签名.公钥加密的消息只能用私钥解密,私钥签名的消息只能用公钥检验签名。

keytool生成的正式都是二进制 data,OPENSSL标准的PEM+key文件,即ascii文本格式的密钥。OpenSSL是SSL/TLS协议的开源实现。它既能处理原有证书,也可以创建新证书,它可以运行在各种平台上,包括Linux、MacOS X和Windows。

JKSPKCS#12都是比较常用的两种密钥库格式/标准。对于前者,搞Java开发,尤其是接触过HTTPS平台的朋友,并不陌生。JKS文件(通常为*.jks或*.keystore,扩展名无关)可以通过Java原生工具——KeyTool生成;而后者PKCS#12文件(通常为*.p12或*.pfx,意味个人信息交换文件),则是通过更为常用的OpenSSL工具产生。 
当然,这两者之间是可以通过导入/导出的方式进行转换的!当然,这种转换需要通过KeyTool工具进行! 


0 0
原创粉丝点击