成人AV在线无码|婷婷五月激情色,|伊人加勒比二三四区|国产一区激情都市|亚洲AV无码电影|日av韩av无码|天堂在线亚洲Av|无码一区二区影院|成人无码毛片AV|超碰在线看中文字幕

SSL編程

SSL 通信SSL 編程使用客戶(hù)機(jī)/服務(wù)器模式,二者之間的通信使用SSL 協(xié)議進(jìn)行加密。本節(jié)先通過(guò)最簡(jiǎn)單的程序介紹服務(wù)器和客戶(hù)程序之間如何通過(guò)SSL 進(jìn)行加密通信。 1 SSL服務(wù)器★ 實(shí)例說(shuō)明本實(shí)例

SSL 通信

SSL 編程使用客戶(hù)機(jī)/服務(wù)器模式,二者之間的通信使用SSL 協(xié)議進(jìn)行加密。本節(jié)先通過(guò)最簡(jiǎn)單的程序介紹服務(wù)器和客戶(hù)程序之間如何通過(guò)SSL 進(jìn)行加密通信。 1 SSL服務(wù)器

★ 實(shí)例說(shuō)明

本實(shí)例編寫(xiě)了一個(gè)最簡(jiǎn)單的SSL 服務(wù)器程序,它接受客戶(hù)程序建立連接,并以加密方式向客戶(hù)程序發(fā)送一串字符Hi 。

SSL 服務(wù)器程序運(yùn)行時(shí)需要指定密鑰庫(kù),以便向客戶(hù)程序證明自己的身份。本實(shí)例演示了通過(guò)編程指定密鑰庫(kù)和通過(guò)java 命令選項(xiàng)指定密鑰庫(kù)的兩種運(yùn)行方式。 ★ 編程思路:

SSL 編程和基于Socket 的編程類(lèi)似,首先創(chuàng)建ServerSocket 對(duì)象,傳入端口號(hào),然后執(zhí)行ServerSocket 對(duì)象的accept( )方法獲取Socket 類(lèi)型的對(duì)象,并偵聽(tīng)端口以等待客戶(hù)程序和服務(wù)器連接。最后通過(guò)Socket 類(lèi)型的對(duì)象獲得輸入和輸出流,通過(guò)輸入和輸出流和客戶(hù)程序進(jìn)行通信。SSL 編程和基于Socket 的編程不同的地方在于其ServerSocket 對(duì)象是通過(guò)一個(gè)特殊的對(duì)象:SSLServerSocketFactory 類(lèi)型的對(duì)象創(chuàng)建的,這樣以后的輸入和輸出流將自動(dòng)按照SSL 協(xié)議指定的方法交換密鑰并對(duì)數(shù)據(jù)進(jìn)行加密。此外,需要指定包含證書(shū)的密鑰庫(kù),以便客戶(hù)程序確定SSL 服務(wù)器是否可靠。

具體步驟如下:

(1) 設(shè)置密鑰庫(kù)及口令

System.setProperty("javax.net.ssl.keyStore",

"mykeystore");

System.setProperty("javax.net.ssl.keyStorePassword",

"wshr.ut");

分析:通過(guò)System 類(lèi)的靜態(tài)方法setProperty( ) 可以設(shè)置系統(tǒng)參數(shù)。方法的第一個(gè)參數(shù)是系統(tǒng)參數(shù)的名稱(chēng),第二個(gè)參數(shù)是為系統(tǒng)參數(shù)設(shè)置的值。作為SSL 服務(wù)器程序,主要需要設(shè)置兩個(gè)系統(tǒng)參數(shù):javax.net.ssl.keyStore 指定密鑰庫(kù)的名稱(chēng),javax.net.ssl.keyStorePassword 指定密鑰庫(kù)的密碼。

這里不妨使用5.1節(jié)得到的密鑰庫(kù)mykeystore ,其密碼為wshr.ut 。密鑰庫(kù)中必須存放私鑰和證書(shū),此外為私鑰設(shè)置的密碼應(yīng)該和密鑰庫(kù)的密碼相同。程序?qū)⒆詣?dòng)從密鑰庫(kù)中提取證書(shū)。

(2) 創(chuàng)建SSLServerSocketFactory 類(lèi)型的對(duì)象

SSLServerSocketFactory ssf= (SSLServerSocketFactory)

SSLServerSocketFactory .getDefault( );

分析:執(zhí)行javax.net.ssl 包中SSLServerSocketFactory 類(lèi)的靜態(tài)方法getDefault( ) ,經(jīng)過(guò)強(qiáng)制轉(zhuǎn)換獲得SSLServerSocketFactory 類(lèi)型的對(duì)象,后面將用它獲取ServerSocket 對(duì)象。

(3) 創(chuàng)建ServerSocket 類(lèi)型的對(duì)象

ServerSocket ss=ssf.createServerSocket(5432);

,

分析:執(zhí)行上一步得到的SSLServerSocketFactory 對(duì)象的createServerSocket ( )方法獲得ServerSocket 類(lèi)型的對(duì)象,方法參數(shù)中指定一個(gè)整數(shù)作為端口號(hào),其值一般在1~ 65535之間,其中1~1023一般用于知名的端口號(hào)或特定的UNIX 服務(wù),臨時(shí)使用的端口號(hào)可取1024~ 65535之間的整數(shù)。

一臺(tái)計(jì)算機(jī)上往往會(huì)運(yùn)行不同的服務(wù)程序提供不同的服務(wù),這些程序應(yīng)使用不同的端口號(hào),這樣,當(dāng)服務(wù)器收到客戶(hù)程序發(fā)來(lái)的請(qǐng)求時(shí),通過(guò)端口號(hào)確定哪個(gè)服務(wù)器程序與之通信。

(4) 等待客戶(hù)程序連接

Socket s=ss.accept( );

分析:執(zhí)行上一步得到的ServerSocket 對(duì)象的accept ( )方法,程序?qū)⒃诖颂帓炱穑却蛻?hù)程序建立連接。該方法返回的Socket 類(lèi)型的對(duì)象可用于和客戶(hù)程序之間的通信。

(5) 建立輸出流

PrintStream out = new PrintStream(s.getOutputStream( ));

out.println("Hi");

分析:執(zhí)行上一步得到的Socket 對(duì)象的getOutputStream( ) 方法可以得到輸出流,通過(guò)該輸出流發(fā)送的信息將加密傳遞給客戶(hù)程序。這里不妨使用輸出流創(chuàng)建PrintStream 類(lèi)型的對(duì)象,以便通過(guò)println( )語(yǔ)句向客戶(hù)程序打印字符串。

如果服務(wù)器程序同時(shí)需要處理客戶(hù)程序發(fā)來(lái)的字符串,可以再通過(guò)Socket 對(duì)象的getInputStream( )方法得到輸入流,從輸入流讀取的信息即客戶(hù)發(fā)來(lái)的信息。 ★代碼與分析:

完整代碼如下:

import java.net.*;

import java.io.*;

import javax.net.ssl.*;

public class MySSLServer{

public static void main(String args[ ]) throws Exception{

System.setProperty("javax.net.ssl.keyStore",

"mykeystore");

System.setProperty("javax.net.ssl.keyStorePassword",

"wshr.ut");

SSLServerSocketFactory ssf=(SSLServerSocketFactory)

SSLServerSocketFactory.getDefault( );

ServerSocket ss=ssf.createServerSocket(5432);

System.out.println("Waiting for connection...");

while(true){

Socket s=ss.accept( ); PrintStream out = new PrintStream(s.getOutputStream( )); out.println("Hi");

out.close( );

s.close( );

}

}

}

,

為了讓程序接受到一個(gè)連接請(qǐng)求并發(fā)送完“Hi ”后能繼續(xù)接受其他客戶(hù)程序建立連接,程序中將Socket s=ss.accept( )及其輸入/輸出處理放在了一個(gè)while 循環(huán)當(dāng)中。

★運(yùn)行程序

由于SSL 協(xié)議需要通過(guò)數(shù)字證書(shū)向客戶(hù)表明服務(wù)器是否值得信任,因此當(dāng)前目錄下必須有密鑰庫(kù),本實(shí)例不妨使用5.1節(jié)得到的密鑰庫(kù)mykeystore ,將其拷貝到當(dāng)前目錄下,然后輸入“java MySSLServer ”運(yùn)行程序,當(dāng)?shù)却欢螘r(shí)間完成初始化后,屏幕顯示:“Waiting for connection...” ,此時(shí)開(kāi)始等待客戶(hù)程序的連接。

編程第1步設(shè)置系統(tǒng)參數(shù)也可以不在程序中指定,而是通過(guò)java 命令選項(xiàng)來(lái)指定。例如如果省略了編程第1步,則可輸入“java -Djavax.net.ssl.keyStore=mykeystore -Djavax.net.ssl.keyStorePassword=wshr.ut MySSLServer ”來(lái)運(yùn)行程序,這樣程序本身更具有靈活性。

為了使客戶(hù)程序能夠順利驗(yàn)證該服務(wù)器提供的證書(shū),應(yīng)該把mykeystore 中所使用的證書(shū)或其簽發(fā)者的證書(shū)提供給客戶(hù)程序。這在下一小節(jié)“運(yùn)行程序”部分將詳細(xì)說(shuō)明。 2 最簡(jiǎn)單的SSL 客戶(hù)程序

★ 實(shí)例說(shuō)明

本實(shí)例編寫(xiě)了一個(gè)最簡(jiǎn)單的SSL 客戶(hù)程序,它和運(yùn)行1小節(jié)程序的計(jì)算機(jī)建立連接,接受其發(fā)來(lái)的字符串并自動(dòng)對(duì)其進(jìn)行解密。本實(shí)例同時(shí)演示了通過(guò)程序指定密鑰庫(kù)和通過(guò)java 命令選項(xiàng)指定密鑰庫(kù)的兩種運(yùn)行方式。

★ 編程思路:

SSL 客戶(hù)端的編程也和基于Socket 的客戶(hù)端編程類(lèi)似。首先得到Socket 類(lèi)型的對(duì)象,然后通過(guò)Socket 類(lèi)型的對(duì)象獲得輸入和輸出流,通過(guò)輸入和輸出流和服務(wù)器程序進(jìn)行通信。和服務(wù)器程序類(lèi)似,SSL 客戶(hù)端編程和基于Socket 的客戶(hù)端編程不同的地方在于其Socket 對(duì)象是通過(guò)一個(gè)特殊的對(duì)象:SSLSocketFactory 類(lèi)型的對(duì)象創(chuàng)建的。

具體步驟如下:

(1) 設(shè)置客戶(hù)程序信任的密鑰庫(kù)

System.setProperty("javax.net.ssl.trustStore",

"clienttrust");

分析:客戶(hù)端欲和SSL 服務(wù)器通信,則必須信任SSL 服務(wù)器程序所使用的數(shù)字證書(shū)。因此客戶(hù)程序應(yīng)該將所信任的證書(shū)放在一個(gè)密鑰庫(kù)中(本實(shí)例“運(yùn)行程序”部分給出了如何創(chuàng)建這樣的密鑰庫(kù))。這里不妨假定客戶(hù)程序信任的證書(shū)放在文件名為clienttrust 的密鑰庫(kù)中。

通過(guò)System 類(lèi)的靜態(tài)方法setProperty( ) 可以設(shè)置系統(tǒng)參數(shù)javax.net.ssl.trustStore ,可以在程序中指定該文件名。由于clienttrust 中存放的只是可以公開(kāi)的證書(shū),因此程序中不需要給出密鑰庫(kù)的密碼。

(2) 創(chuàng)建SSLSocketFactory 類(lèi)型的對(duì)象

SSLSocketFactory ssf= (SSLSocketFactory)

SSLSocketFactory.getDefault( );

分析:執(zhí)行javax.net.ssl 包中SSLSocketFactory 類(lèi)的靜態(tài)方法getDefault( ) ,經(jīng)過(guò)強(qiáng)制轉(zhuǎn)換獲得SSLSocketFactory 類(lèi)型的對(duì)象,后面將用它獲取Socket 對(duì)象。

(3) 創(chuàng)建Socket 類(lèi)型的對(duì)象,連接服務(wù)器程序

Socket s = ssf.createSocket("127.0.0.1", 5432);

,

分析:執(zhí)行上一步得到的SSLSocketFactory 對(duì)象的createSocket ( )方法和服務(wù)器指定端口建立連接。方法的第一個(gè)參數(shù)是字符串形式的服務(wù)器IP 地址或域名,如果只有一臺(tái)計(jì)算機(jī),客戶(hù)和服務(wù)器程序都在同一臺(tái)計(jì)算機(jī)上運(yùn)行,則可以使用“127.0.0.1”作為服務(wù)器的IP 地址,或“Localhost ”作為服務(wù)器的域名。第二個(gè)參數(shù)即7.1.1小節(jié)的服務(wù)器程序在第3步指定的端口號(hào)。

(4) 建立輸出流

BufferedReader in = new BufferedReader(

new InputStreamReader(s.getInputStream( )));

String x=in.readLine( )

分析:執(zhí)行上一步得到的Socket 對(duì)象的getInputStream( ) 方法可以得到輸入流,通過(guò)該輸入流讀取服務(wù)器程序發(fā)送來(lái)的信息并自動(dòng)解密。這里不妨使用輸入流創(chuàng)建BufferedReader 類(lèi)型的對(duì)象,以便通過(guò)readLine( )語(yǔ)句讀取字符串。

如果客戶(hù)程序同時(shí)需要向服務(wù)器程序發(fā)送信息,可以再通過(guò)Socket 對(duì)象的getOutputStream( ) 方法得到輸出流,通過(guò)輸出流發(fā)送的信息可以被服務(wù)器程序的輸入流讀取到。

★代碼與分析:

完整代碼如下:

import java.net.*;

import java.io.*;

import javax.net.ssl.*;

public class MySSLClient{

public static void main(String args[ ]) throws Exception {

System.setProperty("javax.net.ssl.trustStore",

"clienttrust");

SSLSocketFactory ssf=

(SSLSocketFactory) SSLSocketFactory.getDefault( );

Socket s = ssf.createSocket("127.0.0.1", 5432);

BufferedReader in = new BufferedReader(

new InputStreamReader(s.getInputStream( )));

String x=in.readLine( );

System.out.println(x);

in.close( );

}

}

★運(yùn)行程序

服務(wù)器程序假定具有密鑰庫(kù)mykeystore ,假定具有證書(shū)文件mytest.cer 。將該文件存放在客戶(hù)程序所在目錄中,以便客戶(hù)程序向服務(wù)器程序確認(rèn)信任該證書(shū)。為了在程序中使用,需將該證書(shū)導(dǎo)入密鑰庫(kù),操作如下:

C:javach7Client>keytool -import -alias mytest -file mytest.cer -keystore clienttrust

,

輸入keystore 密碼: 123456

Owner: CN=Xu Yingxiao, OU=Network Center, O=Shanghai University, L=ZB, ST=Shangh

ai, C=CN

發(fā)照者: CN=Xu Yingxiao, OU=Network Center, O=Shanghai University, L=ZB, ST=Shan

ghai, C=CN

序號(hào): 3deec043

有效期間: Thu Dec 05 10:56:03 CST 2002 至: Sun Nov 17 10:56:03 CST 2013

認(rèn)證指紋:

MD5: B2:DC:75:CD:60:B7:1E:7A:97:EE:E8:A4:31:D6:26:C6

SHA1: 32:E5:89:16:7E:25:7F:86:16:94:34:36:95:44:D7:CF:14:C8:F2:1E

信任這個(gè)認(rèn)證? [否]: 是

認(rèn)證已添加至keystore 中

該操作將證書(shū)my.cer 導(dǎo)入密鑰庫(kù)clienttrust 。

運(yùn)行程序之前檢查一下1小節(jié)的程序是否已經(jīng)運(yùn)行,其DOS 窗口停留在“Waiting for connection... ”提示語(yǔ)句。客戶(hù)程序可以在同一臺(tái)計(jì)算機(jī)上再開(kāi)設(shè)一個(gè)DOS 窗口來(lái)運(yùn)行,也可在另一臺(tái)聯(lián)網(wǎng)的計(jì)算機(jī)上運(yùn)行,這時(shí)程序中的IP 地址:127.0.0.1應(yīng)該改為運(yùn)行1小節(jié)服務(wù)器程序所在計(jì)算機(jī)的實(shí)際IP 地址。

在DOS 窗口輸入“java MySSLClient ”運(yùn)行客戶(hù)程序,程序?qū)@示服務(wù)器程序發(fā)來(lái)的“Hi ”。如果用抓包軟件捕捉客戶(hù)程序和服務(wù)器程序之間的通信,可以發(fā)現(xiàn)通信內(nèi)容是以密文傳遞的。

和服務(wù)器程序一樣,編程第1步設(shè)置系統(tǒng)參數(shù)也可以不在程序中指定,而是通過(guò)java 命令選項(xiàng)來(lái)指定。例如如果省略了編程第1步,則可輸入“java -Djavax.net.ssl.trustStore=clienttrust MySSLClient ”來(lái)運(yùn)行程序,這樣程序本身更具有靈活性。

標(biāo)簽: