国产成人毛片视频|星空传媒久草视频|欧美激情草久视频|久久久久女女|久操超碰在线播放|亚洲强奸一区二区|五月天丁香社区在线|色婷婷成人丁香网|午夜欧美6666|纯肉无码91视频

SSL編程

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

SSL 通信

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

★ 實(shí)例說明

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

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

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

具體步驟如下:

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

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

"mykeystore");

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

"wshr.ut");

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

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

(2) 創(chuàng)建SSLServerSocketFactory 類型的對象

SSLServerSocketFactory ssf= (SSLServerSocketFactory)

SSLServerSocketFactory .getDefault( );

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

(3) 創(chuàng)建ServerSocket 類型的對象

ServerSocket ss=ssf.createServerSocket(5432);

,

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

一臺計(jì)算機(jī)上往往會運(yùn)行不同的服務(wù)程序提供不同的服務(wù),這些程序應(yīng)使用不同的端口號,這樣,當(dāng)服務(wù)器收到客戶程序發(fā)來的請求時,通過端口號確定哪個服務(wù)器程序與之通信。

(4) 等待客戶程序連接

Socket s=ss.accept( );

分析:執(zhí)行上一步得到的ServerSocket 對象的accept ( )方法,程序?qū)⒃诖颂帓炱?,等待客戶程序建立連接。該方法返回的Socket 類型的對象可用于和客戶程序之間的通信。

(5) 建立輸出流

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

out.println("Hi");

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

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

完整代碼如下:

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( );

}

}

}

,

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

★運(yùn)行程序

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

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

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

★ 實(shí)例說明

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

★ 編程思路:

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

具體步驟如下:

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

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

"clienttrust");

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

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

(2) 創(chuàng)建SSLSocketFactory 類型的對象

SSLSocketFactory ssf= (SSLSocketFactory)

SSLSocketFactory.getDefault( );

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

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

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

,

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

(4) 建立輸出流

BufferedReader in = new BufferedReader(

new InputStreamReader(s.getInputStream( )));

String x=in.readLine( )

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

如果客戶程序同時需要向服務(wù)器程序發(fā)送信息,可以再通過Socket 對象的getOutputStream( ) 方法得到輸出流,通過輸出流發(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ù)器程序假定具有密鑰庫mykeystore ,假定具有證書文件mytest.cer 。將該文件存放在客戶程序所在目錄中,以便客戶程序向服務(wù)器程序確認(rèn)信任該證書。為了在程序中使用,需將該證書導(dǎo)入密鑰庫,操作如下:

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

序號: 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

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

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

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

運(yùn)行程序之前檢查一下1小節(jié)的程序是否已經(jīng)運(yùn)行,其DOS 窗口停留在“Waiting for connection... ”提示語句??蛻舫绦蚩梢栽谕慌_計(jì)算機(jī)上再開設(shè)一個DOS 窗口來運(yùn)行,也可在另一臺聯(lián)網(wǎng)的計(jì)算機(jī)上運(yùn)行,這時程序中的IP 地址:127.0.0.1應(yīng)該改為運(yùn)行1小節(jié)服務(wù)器程序所在計(jì)算機(jī)的實(shí)際IP 地址。

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

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

標(biāo)簽: