《《安全网络通信》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《安全网络通信》PPT课件.ppt(69页珍藏版)》请在三一办公上搜索。
1、Java网络程序设计,安全网络通信,SSL简介JSSE简介创建基于SSL的安全服务器和安全客户,主要内容,SSL简介,SSL(Server Socket Layer)是一种保证网络上的两个节点进行安全通信的协议。IETF(Internet Engineering Task Force)对SSL作了标准化,制订RFC2246规范,并将其称为TLS(Transport Layer Security)。从技术上讲,目前的TLS1.0与SSL3.0的差别非常微小。,SSL简介,建立在SSL协议上的HTTP被称为HTTPS协议。HTTP使用默认端口为80,而HTTPS使用默认端口为443。,SSL简介,
2、用户在网上商店购物,当输入信用卡信息,进行网上支付交易时,存在以下不安全因素:(1)信用卡信息在网络上传输时有可能被他人截获。(2)用户发送的信息在网络上传输时可能被非法篡改,数据完整性被破坏。(3)用户正在访问非法Web站点,专门从事网上欺诈活动,比如骗取客户的资金。,SSL采用加密技术实现安全通信,保证通信数据的保密性和完整性,并且保证通信双方可以验证对方的身份。,加密通信,数据从一端发送到另一端时,发送者先对数据加密,然后再把它发送给接收者。这样,在网络上传输的是经过加密的数据。如果有人在网络上非法截获这批数据,由于没有解密的密钥,就无法获得真正的原始数据。接收者接收到加密的数据后,先对
3、数据解密,然后再处理。,加密通信示意图,安全证书,除了对数据加密通信,SSL还采用身份认证机制,确保通信双方都可以验证对方的真实身份。SSL通过安全证书证明客户或服务器的身份。当客户通过安全连接和服务器通信时,服务器会先向客户出示它的安全证书,这个证书声明该服务器是安全的而且的确是这个服务器。,安全证书,每一个证书在全世界范围内都是惟一的,其他非法服务器无法假冒原始服务器的身份。可以把安全证书比作电子身份证。,获取安全证书的两种方式,方式一:从权威机构购买证书。方式二:创建自我签名的证书。,从权威机构获得证书,安全证书可以有效的保证通信双方的身份的可信性。安全证书采用加密技术制作,他人几乎无法
4、伪造。安全证书由国际权威的证书机构(CA,Certificate Authority)如VeriSign()和Thawte()颁发,它们保证证书的可信性。申请安全证书时,必须支付一定的费用。一个安全证书只对一个IP地址有效。,公钥加密,安全证书既包含用于加密数据的密钥,又包含用于证实身份的数字签名。安全证书采用公钥加密技术。公钥加密是指使用一对非对称的密钥进行加密或解密。每一对密钥由公钥和私钥组成。公钥被广泛发布。私钥是隐密的,不公开。用公钥加密的数据只能够被私钥解密。反过来,使用私钥加密的数据只能被公钥解密。,创建自我签名证书,某些场合下,通信双方只关心数据在网络上可以安全传输,并不需要对方
5、进行身份验证。这种情况下,可以创建自我签名(self-assign)的证书,比如通过Sun公司提供的keytool工具就可以创建这样的证书。,制作证书的工具keytool,JDK1.4以上版本中包含这一工具,它的位置为:binkeytool.exe,此外,也可以到以下站点单独下载keytool:通过keytool工具创建证书的命令为:keytool-genkey-alias mystore-keyalg RSA-keystore C:test.keys,keytool命令将生成包含一对非对称密钥和自我签名的证书,命令中参数的意思:genkey:生成一对非对称密钥。alias:指定密钥对的别名,
6、该别名是公开的。keyalg:指定加密算法,本例中采用通用的RSA算法。keystore:指定安全证书的存放路径。,SSL握手,客户与服务器通信时,首先要进行SSL握手。SSL握手主要完成:(1)协商使用的加密套件。加密套件中包括一组加密参数,这些参数指定加密算法和密钥的长度等信息。(2)验证对方的身份。此操作是可选的。(3)确定使用的加密算法。,SSL简介JSSE简介创建基于SSL的安全服务器和安全客户,主要内容,JSSE(Java Secure Socket Extension),JSSE封装底层复杂的安全通信细节,使开发人员能方便的利用它开发安全的网络应用程序。,JSSE主要包括四个包:
7、包:包括进行安全通信的类,如SSLServerSocket和SSLSocket类。(2)包:包括安全套接字的工厂类,如SSLServerSocketFactory和SSLSocketFactory类。包:包括处理安全证书的类,如X509Certificate类。X.509是由国际电信联盟(ITU-T)制定的安全证书的标准。包:包括SUN公司提供的JSSE的实现类。,JSSE具有以下特征,纯粹用Java语言编写。可以出口到大多数国家。提供支持SSL2.0和SSL3.0的JSSE API,,并且提供SSL 3.0 的JSSE实现。提供支持TLS1.0的JSSE API和JSSE实现。提供用于创建安
8、全连接的类,如SSLSocket、SSLServerSocket和SSLEngine。,JSSE具有以下特征,支持加密通信。支持客户端和服务器端的身份验证。支持SSL会话。支持一些常用加密算法,比如RSA(加密长度2048位)、RC4(密钥长度128位)和DH(密钥长度1024位)。,JSSE API的主要类框图,JSSE中负责安全通信的最核心类是SSLServerSocket类与SSLSocket类,它们分别是ServerSocket与Socket类的子类。SSLSocket对象由SSLSocketFactory创建;SSLServerSocket的accept()方法也会创建SSLSock
9、et。SSLServerSocket对象由SSLServerSocketFactory创建。SSLSocketFactory、SSLServerSocketFactory以及SSLEngine对象都由SSLContext对象创建。SSLEngine类用于支持非阻塞的安全通信。,下列createSocket()方法创建采用SSL协议的SSLSocket对象。public void createSocket()throws Exceptionfactory=(SSLSocketFactory)SSLSocketFactory.getDefault();socket=(SSLSocket)facto
10、ry.createSocket(host,port);Stringsupported=socket.getSupportedCipherSuites();socket.setEnabledCipherSuites(supported);,C/S安全管理,在进行安全通信时,要求客户端与服务器端都支持SSL或TCL协议。客户端与服务器端可能都需要设置用于证实自身身份的安全证书,还要设置信任对方的哪些安全证书。,KeyStore类,存放安全证书。以下程序创建一个KeyStore对象,它从test.keys文件中加载安全证书。String passphrase=654321;/JKS是SUN支持的Ke
11、yStore的类型KeyStore keyStore=KeyStore.getInstance(JKS);char password=passphrase.toCharArray();/password参数用于打开安全证书keyStore.load(new FileInputStream(test.keys),password);,KeyManager类,选择证实自身身份的安全证书,把它发送给对方。KeyManagerFactory负责创建KeyManager对象,如:KeyManagerFactory keyManagerFactory=KeyManagerFactory.getInstan
12、ce(SunX509);keyManagerFactory.init(keyStore,password);KeyManager keyManagers=keyManagerFactory.getKeyManagers();,TrustManager类,决定是否信任对方的安全证书。TruesManagerFactory负责创建TrustManager对象,如:TrustManagerFactory trustManagerFactory=TrustManagerFactory.getInstance(SunX509);trustManagerFactory.init(keyStore);Tru
13、stManager trustManagers=trustManagerFactory.getTrustManagers();,SSLContext类,设置与安全通信有关的各种信息,如使用的协议(SSL或者TLS),自身的安全证书以及对方的安全证书。SSLContext还负责构造SSLServerSocketFactory、SSLSocketFactory和SSLEngine对象。,以下程序创建并初始化一个SSLContext对象,然后由它创建一个SSLServerSocketFactory对象:SSLContext sslCtx=SSLContext.getInstance(TLS);/采用
14、TLS协议sslCtx.init(kmf.getKeyManagers(),tmf.getTrustManagers(),null);SSLServerSocketFactory ssf=sslCtx.getServerSocketFactory();,SSLServerSocketFactory类,负责创建SSLServerSocket对象:SSLServerSocket serverSocket=(SSLServerSocket)sslServerSocketFactory.createServerSocket(8000);/监听端口8000,SSLServerSocketFactory对
15、象有两种创建方法:(1)调用SSLContext类的getServerSocketFactory()方法。(2)调用SSLServerSocketFactory类的静态getDefault()方法。,SSLSocketFactory类,负责创建SSLSocket对象:SSLSocket socket=(SSLSocket)sslSocketFactory.createSocket(localhost,8000);SSLSocketFactory对象有两种创建方法:(1)调用SSLContext类的getSocketFactory()方法。(2)调用SSLSocketFactory类的静态get
16、Default()方法。,SSLSocket类,SSLSocket类是Socket类的子类,因此两者用法有许多相似之处。SSLSocket类具有与安全通信有关的方法:(1)设置加密套件(2)处理握手结束事件(3)管理SSL会话(4)客户端模式,设置加密套件,SSLSocket类的getSupportedCipherSuites()方法返回一个字符串数组,包含当前SSLSocket对象所支持的加密套件组。SSLSocket类的setEnabledCipherSuites(String suites)方法设置当前SSLSocket对象的可使用加密套件组。可使用的加密套件组应该是所支持的加密套件组的
17、子集。,以下代码启用具有高加密强度的加密套件,可以提高该通信端的安全性,禁止那些不支持强加密的通信端连接当前通信端:String strongSuites=SSL_DES_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA;sslSocket.setEnabledCipherSuites(strongSuites);,处理握手结束事件,SSL握手需要花费很长时间,当SSL握手完成,会发出一个HandshakeCompletedEvent
18、事件,该事件由HandshakeCompletedListener负责监听。SSLSocket类的addHandshakeCompletedListener()方法负责注册HandshakeCompletedListener监听器。,HandshakeCompletedEvent类提供获取与握手事件相关的信息的方法:(1)public SSLSession getSession()/获得会话(2)public String getCipherSuite()/获得实际使用的加密套件(3)public SSLSocket getSocket()/获得发出该事件的套接字HandshakeComple
19、tedListener接口的以下方法负责处理握手结束事件:public void handshakeCompleted(HandshakeCompletedEvent event),SSLSocket类用于管理SSL会话:为了提高安全通信的效率,SSL协议允许多个SSLSocket共享同一个SSL会话。在同一个会话中,只有第一个打开的SSLSocket需要进行SSL握手,负责生成密钥以及交换密钥,其余的SSLSocket都共享密钥信息。,byte getId()/获得会话ID。每个会话都有惟一的IDString getCipherSuite()/获得实际使用的加密套件long getCreat
20、ionTime()/获得创建会话的时间long getLastAccessedTime()/获得最近一次访问会话的时间。访问会话是指程序创建一个使用该会话的SSLSocket。String getPeerHost()/获得通信对方的主机int getPeerPort()/获得通信对方的端口void invalidate()/使会话失效boolean isValid()/判断会话是否有效,SSLSession接口表示SSL会话,SSLSocket的getSession()返回SSLSocket所属会话。SSLSocket的setEnableSessionCreation(boolean flag
21、)决定SSLSocket是否允许创建新会话。flag参数默认值为true。(1)如果flag为true,对于新创建的SSLSocket,如果当前已经有可用会话,就直接加入该会话,如果没有可用会话,就创建一个新会话。(2)如果flag为false,对于新创建的SSLSocket,如果当前已经有可用会话,就直接加入该会话,如果没有可用会话,那么该SSLSocket无法与对方进行安全通信。,SSLSocket的startHandshake()显式执行一次SSL握手。该方法用途:(1)使得会话使用新的密钥。(2)使得会话使用新的加密套件。(3)重新开始一个会话。为了保证不重用原先的会话,应该先将原先的
22、会话失效:socket.getSession().invalidate();socket.startHandshake();,客户端模式,多数情况下客户端无需向服务器证实自己的身份。当一个通信端无需向对方证实自己身份,就称它处于客户模式,否则称它处于服务器模式。SSLSocket的setUseClientMode(boolean mode)设置客户模式或者服务器模式。如果mode参数为true,表示客户模式,即无需向对方证实自己的身份;如果mode参数为false,表示服务器模式,即需要向对方证实自己的身份。,当SSLSocket处于服务器模式,通过以下方法决定是否要求对方提供身份认证:(1)
23、setWantClientAuth(boolean want):当want参数为true,表示希望对方提供身份认证。如果对方未出示安全证书,连接不会中断,通信继续进行。(2)setNeedClientAuth(boolean need):当need参数为true,表示要求对方必须提供身份认证。如果对方未出示安全证书,连接中断,通信无法继续。,SSLServerSocket类是ServerSocket类的子类,因此两者的用法有许多相似之处。SSLServerSocket类还具有与安全通信有关的方法。这些方法与SSLSocket类中的同名方法具有相同的作用。,String getSupported
24、CipherSuites():返回一个字符串数组,它包含当前SSLServerSocket对象所支持的加密套件组。void setEnabledCipherSuites(String suites):设置当前SSLServerSocket对象可使用的加密套件组。String getEnabledCipherSuites():返回一个字符串数组,它包含当前SSLServerSocket对象可使用的加密套件组。,设置加密套件的方法,管理SSL会话,void setEnableSessionCreation(boolean flag):决定由当前SSLServerSocket对象创建的SSLSock
25、et对象是否允许创建新的会话。boolean getEnableSessionCreation():判断由当前SSLServerSocket对象创建的SSLSocket对象是否允许创建新的会话。,设置客户端模式,void setUseClientMode(boolean mode):当mode参数为true,表示客户端模式。void setWantClientAuth(boolean want):当want参数为true,表示希望对方提供身份认证。void setNeedClientAuth(boolean need):当need参数为true,表示要求对方必须提供身份认证。,SSLEngin
26、e类,SSLEngine类与SocketChannel类联合使用,实现非阻塞的安全通信。SSLEngine类封装与安全通信有关的细节,把应用程序发送的应用数据打包为网络数据。(打包是对应用数据进行加密,加入SSL握手数据,把它变为网络数据。SSLEngine类能把接收到的网络数据展开为应用数据。(展开是指对网络数据解密)SSLEngine类的wrap()方法负责打包应用数据,unwrap()方法负责展开网络数据。,在图3中,SocketChannel类负责发送和接收网络数据,SSLEngine类负责网络数据与应用数据之间的转换。,图3,SSLEngine类的wrap()以及unwrap()方法
27、都返回一个SSLEngineResult对象,它描述执行wrap()或unwrap()方法的结果。,SSLEngineResult类的getHandshakeStatus()返回SSL握手状态,如果取值为HandshakeStatus.NEED_TASK,表明握手没有完成,应该继续完成握手任务:if(result.getHandshakeStatus()=HandshakeStatus.NEED_TASK)Runnable runnable;while(runnable=engine.getDelegatedTask()!=null)runnable.run();,SSL简介JSSE简介创建基
28、于SSL的安全服务器和安全客户,主要内容,创建基于SSL的安全服务器和安全客户,SSL编程使用客户机/服务器模式,二者之间的通信使用SSL协议进行加密。本节先通过最简单的程序介绍服务器和客户程序之间如何通过SSL进行加密通信。,示例1:简单的SSL服务器程序,接受客户程序建立连接,并以加密方式向客户程序发送一串字符。(MySSLServer.java)SSL服务器程序运行时需要指定密钥库,以便向客户程序证明自己的身份。本实例演示通过编程指定密钥库和通过java命令选项指定密钥库的两种运行方式。,编程思路,基于Socket编程:(1)创建ServerSocket对象,传入端口号,(2)执行Ser
29、verSocket对象的accept()获取Socket类型的对象,并侦听端口以等待客户程序的请求连接。(3)通过Socket类型的对象获得输入和输出流,通过输入和输出流和客户程序进行通信。,SSL编程与基于Socket编程不同:(1)其ServerSocket对象通过一个特殊对象SSLServerSocketFactory类型对象创建;(2)输入和输出流将自动按照SSL协议指定的方法交换密钥并对数据进行加密。(3)需要指定包含证书的密钥库,以便客户程序确定SSL服务器是否可靠。,Step1:设置密钥库及口令,System.setProperty(,mykeystore);System.set
30、Property(,wshr.ut);,分析:通过System类的setProperty()可以设置系统参数。第一个参数是系统参数名称,第二个参数是为系统参数设置的值。作为SSL服务器程序,主要需要设置两个系统参数:指定密钥库的名称,指定密钥库的密码。,Step2:创建SSLServerSocketFactory类型的对象,SSLServerSocketFactory ssf=(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();,分析:执行包中SSLServerSocketFactory类静态方法getDefault(),经过
31、强制转换获得SSLServerSocketFactory类型对象,将用它获取ServerSocket对象。,Step3:创建ServerSocket类型的对象,ServerSocket s=ssf.createServerSocket(5432);,分析:上一步得到SSLServerSocketFactory对象的createServerSocket()获得ServerSocket类型对象,方法参数中指定一个整数作为端口号,其值一般在1 65535之间,其中临时使用的端口号可取1024 65535之间的整数。,Step4:等待客户程序连接,Socket s=ss.accept();,分析:执行
32、上一步得到的ServerSocket对象的accept(),程序将在此处挂起,等待客户程序建立连接。该方法返回的Socket类型的对象可用于和客户程序之间的通信。,的,Step5:建立输出流,PrintStream out=new PrintStream(s.getOutputStream();out.println(“hello,Im 007!);,分析:上一步得到的Socket对象getOutputStream()得到输出流,通过该输出流发送的信息将加密传递给客户程序。这里使用输出流创建PrintStream类型对象。如果服务器程序同时处理客户程序发来字符串,可以通过Socket对象get
33、InputStream()得到输入流,从输入流读取客户发来的信息。,的,示例2:简单的客户端程序,它和运行服务器程序的建立连接,接受其发来的字符串并自动对其进行解密。(MySSLClient.java),编程思路,基于Socket的客户端编程:(1)得到Socket类型的对象;(2)通过Socket类型的对象获得输入和输出流,通过输入和输出流和服务器程序进行通信。,SSL客户端编程与Socket客户端编程不同:(1)其Socket对象通过一个特殊对象SSLServerSocketFactory类型对象创建;,Step1:设置客户程序信任的密钥库,System.setProperty(.ssl.
34、trustStore,clienttrust);,分析:客户端欲和SSL服务器通信,则必须信任SSL服务器程序所使用的数字证书。因此客户程序应该将所信任的证书放在一个密钥库中(本实例“运行程序”部分给出了如何创建这样的密钥库)。这里假定客户程序信任的证书放在文件名为clienttrust的密钥库中。,Step2:创建SSLSocketFactory类型的对象,SSLSocketFactory ssf=(SSLSocketFactory)SSLSocketFactory.getDefault();,分析:执行包中SSLSocketFactory类的静态方法getDefault(),经过强制转换获
35、得SSLSocketFactory类型的对象,后面将用它获取Socket对象。,Step3:创建Socket类型对象,连接服务器程序,Socket s=ssf.createSocket(127.0.0.1,5432);,分析:上一步得到SSLSocketFactory对象的createSocket()和服务器指定端口建立连接。第一个参数是服务器IP地址或域名,如果只有一台计算机,使用“127.0.0.1”作为服务器的IP地址,或“Localhost”作为服务器的域名。第二个参数即服务器程序指定的端口号。,Step4:建立输出流,BufferedReader in=new BufferedRea
36、der(new InputStreamReader(s.getInputStream();,分析:执行Socket对象getInputStream()得到输入流,通过该输入流读取服务器程序发送来的信息并自动解密。这里使用输入流创建BufferedReader类型对象,以便通过readLine()语句读取字符串。如果服务器程序同时处理客户程序发来字符串,可以通过Socket对象getOutputStream()得到输出流,从输出流向服务器客户发送信息。,的,练习题1,问题:JSSE支持哪些协议?选项:a)FTPb)SSLc)TLSd)HTTP答案:b,c,练习题2,问题:SSL协议位于哪个层?选
37、项:a)网络层b)应用层c)传输层d)安全套节字层答案:d,练习题3,问题:以下哪些属于SSL协议的内容?选项:a)验证通信对方的身份b)保证数据的可靠传输,数据不会丢失c)对网络上传输的数据加密d)保证不会接收到乱序的数据包答案:a,c,练习题4,问题:以下哪些类的对象可以直接由SSLContext创建?选项:a)SSLServerSocketFactoryb)SSLSocketFactoryc)SSLEngined)SSLSockete)KeyStore答案:a,b,c,练习题5,问题:在SSL协议中,什么叫客户模式?选项:a)当一个通信端作为客户程序运行,就称它处于客户模式。b)当一个通信端无需向对方证实自己身份,就称它处于客户模式。c)当一个通信端要求对方必须提供身份验证,就称它处于客户模式。d)如果一个通信端处于服务器模式,那么另一端就处于客户模式。答案:b,练习题6,问题:关于TrustManager,以下哪些说法正确?选项:a)TrustManager用来证实自己的身份。b)TrustManager用来验证对方的身份。c)如果通信方A要求验证通信方B的身份时,通信方A的程序中必须创建TrustManager。d)如果通信方A要求验证通信方B的身份时,通信方B的程序中必须创建TrustManager。答案:b,c,