windows網(wǎng)絡(luò)編程第9章_第1頁
windows網(wǎng)絡(luò)編程第9章_第2頁
windows網(wǎng)絡(luò)編程第9章_第3頁
windows網(wǎng)絡(luò)編程第9章_第4頁
windows網(wǎng)絡(luò)編程第9章_第5頁
已閱讀5頁,還剩137頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Windows網(wǎng)絡(luò)編程實用教程授課教師:職務(wù):第9章安全套接層協(xié)議SSL課程描述在第5章和第8章中已經(jīng)介紹了Socket(套接字)編程基礎(chǔ)和編程模型。使用這些技術(shù)可以很方便地構(gòu)建高效、實用的客戶機/服務(wù)器應(yīng)用程序。但是普通的Socket模型使用明文傳輸數(shù)據(jù),信息很容易被攔截和監(jiān)聽。隨著電子商務(wù)的普及,在線支付勢在必行,網(wǎng)絡(luò)安全變得尤為重要。本章所介紹的安全套接層協(xié)議SSL可以用來保障在Internet上數(shù)據(jù)傳輸?shù)陌踩?,利用?shù)據(jù)加密技術(shù),可確保數(shù)據(jù)在網(wǎng)絡(luò)上的傳輸過程中不會被截取及竊聽。本章知識點9.1什么是SSL

9.2數(shù)字證書9.3OpenSSL編程基礎(chǔ)9.4OpenSSL編程實例9.1什么是SSL9.1.1SSL簡介和相關(guān)概念9.1.2SSL的握手過程9.1.1SSL簡介和相關(guān)概念打開IE的Internet選項對話框選擇使用的SSL版本SSL協(xié)議的體系結(jié)構(gòu)1.SSL證書SSL證書是數(shù)字證書的一種,在建立SSL連接時,Web服務(wù)器需要一個SSL證書,用于證明網(wǎng)站的真實身份,提高用戶對網(wǎng)站的信任度;有效避免釣魚網(wǎng)站、仿冒網(wǎng)站等網(wǎng)絡(luò)詐騙行為的威脅;

建立SSL安全通道,確??蛻襞c網(wǎng)站之間的信息加密傳輸,保證安全。2.密鑰密鑰是數(shù)據(jù)加密解密過程中的一種參數(shù),它是在明文轉(zhuǎn)換為密文或?qū)⒚芪霓D(zhuǎn)換為明文的算法中輸入的數(shù)據(jù)。密鑰分為兩種:對稱密鑰與非對稱密鑰。對稱密鑰加密非對稱密鑰加密3.CSR文件CSR是CerificateSigningRequest的英文縮寫,即證書簽發(fā)請求文件。證書申請者在申請數(shù)字證書時,由CSP(加密服務(wù)提供者)在生成私鑰的同時生成CSR文件。證書申請者只要把CSR文件提交給證書頒發(fā)機構(gòu),證書頒發(fā)機構(gòu)就可以使用其根證書私鑰簽名生成證書公鑰文件,也就是頒發(fā)給用戶的證書。4.利用MAC算法驗證消息完整性MAC是MessageAuthenticationCodes的縮寫,即消息認證碼。MAC算法是帶私鑰的Hash函數(shù),消息的散列值由只有通信雙方知道的秘私鑰K來控制。此時Hash值稱作MAC。Hash,一般翻譯做"散列",也有直接音譯為"哈希"的,就是把任意長度的輸入,通過散列算法,變換成固定長度的輸出,該輸出就是散列值。5.基于SSL的應(yīng)用層協(xié)議協(xié)議名說明HTTPSHTTP是HypertextTransferProtocol的縮寫,即超文本傳輸協(xié)議。用于規(guī)定瀏覽器和Web服務(wù)器之間互相通信的規(guī)則。HTTPS是HyperTextTransferProtocoloverSecureSocketLayer的縮寫,即基于SSL的超文本傳輸協(xié)議。HTTPS是HTTP的安全版。即在HTTP下加入SSL層POP3SPOP3(PostOfficeProtocol3)即郵局協(xié)議的第3個版本,它是規(guī)定個人計算機如何連接到互聯(lián)網(wǎng)上的郵件服務(wù)器進行收發(fā)郵件的協(xié)議。它是因特網(wǎng)電子郵件的第一個離線協(xié)議標(biāo)準(zhǔn),POP3協(xié)議允許用戶從服務(wù)器上把郵件存儲到本地主機(即自己的計算機)上,同時根據(jù)客戶端的操作刪除或保存在郵件服務(wù)器上的郵件,而POP3服務(wù)器則是遵循POP3協(xié)議的接收郵件服務(wù)器,用來接收電子郵件的。POP3S表示

Pop3(PostOfficeProtocol)Secure,即基于SSL的POP3FTPS在安全套接層的基礎(chǔ)上使用標(biāo)準(zhǔn)的FTP協(xié)議和指令的一種增強型FTP協(xié)議,為FTP協(xié)議和數(shù)據(jù)通道增加了SSL安全功能。FTPS也稱作“FTP-SSL”和“FTP-over-SSL”MIAPSIMAP是InternetMailAccessProtocol的縮寫,它的主要作用是郵件客戶端(例如MSOutlookExpress)可以通過這種協(xié)議從郵件服務(wù)器上獲取郵件的信息,下載郵件等。它與POP3協(xié)議的主要區(qū)別是用戶可以不用把所有的郵件全部下載,可以通過客戶端直接對服務(wù)器上的郵件進行操作。MIAPS是基于SSL的IMAP協(xié)議9.1.2SSL的握手過程在不同情況下,SSL握手過程存在差異。下面介紹以下3種情況的握手過程:(1)只驗證服務(wù)器的SSL握手過程。(2)驗證服務(wù)器和客戶端的SSL握手過程。(3)恢復(fù)原有會話的SSL握手過程。1.只驗證服務(wù)器的SSL握手過程

2.驗證服務(wù)器和客戶端的SSL握手過程3.恢復(fù)原有會話的SSL握手過程9.2數(shù)字證書9.2.1基本概念9.2.2數(shù)字證書的分類9.2.3數(shù)字證書的授權(quán)機構(gòu)9.2.4部署基于數(shù)字證書的HTTPS網(wǎng)站9.2.1基本概念數(shù)字證書是一個經(jīng)證書授權(quán)中心數(shù)字簽名的包含公鑰擁有者信息以及公鑰的文件。最簡單的證書包含一個公鑰、名稱以及證書授權(quán)中心的數(shù)字簽名。數(shù)字證書由一個權(quán)威機構(gòu)——CA機構(gòu),發(fā)行的。CACA是CertificateAuthority的縮寫,即證書授權(quán)中心。作為網(wǎng)絡(luò)營銷交易中受信任的第三方,來解決公鑰體系中公鑰合法性的檢驗問題。CA機構(gòu)是承擔(dān)網(wǎng)上安全交易認證服務(wù)、簽發(fā)數(shù)字證書、確認用戶身份的服務(wù)機構(gòu),是一個具有權(quán)威性、公正性的第三方。截至2014年3月11日,國家工業(yè)和信息化部以資質(zhì)合規(guī)的方式,陸續(xù)向30多家相關(guān)機構(gòu)頒發(fā)了從業(yè)資質(zhì)1.加密、解密當(dāng)發(fā)送一份保密文件時,發(fā)送方使用接收方的公鑰對數(shù)據(jù)加密,而接收方則使用自己的私鑰解密,這樣信息就可以安全無誤地到達目的地了。通過數(shù)字的手段保證加密過程是一個不可逆過程,即只有用私有密鑰才能解密。2.?dāng)?shù)字簽名用戶也可以采用自己的私鑰對信息加以處理,由于密鑰僅為本人所有,這樣就產(chǎn)生了別人無法生成的文件,也就形成了數(shù)字簽名。采用數(shù)字簽名,能夠確認以下兩點:(1)保證信息是由簽名者自己簽名發(fā)送的,簽名者不能否認或難以否認;(2)保證信息自簽發(fā)后到收到為止未曾作過任何修改,簽發(fā)的文件是真實文件。9.2.2數(shù)字證書的分類根據(jù)數(shù)字證書的應(yīng)用情況,可以將其分為個人證書企業(yè)或機構(gòu)身份證書支付網(wǎng)關(guān)證書服務(wù)器證書企業(yè)或機構(gòu)代碼簽名證書安全電子郵件證書個人代碼簽名證書1.個人證書個人證書在網(wǎng)絡(luò)通訊中標(biāo)識個人的身份,證書中包含個人身份信息和個人的公鑰,用于標(biāo)識證書持有人的個人身份。數(shù)字安全證書和對應(yīng)的私鑰存儲于E-key或U盾等安全客戶端中,用于個人在網(wǎng)上進行合同簽定、定單、錄入審核、操作權(quán)限、支付信息等活動中標(biāo)明身份。2.企業(yè)或機構(gòu)身份證書頒發(fā)給企事業(yè)單位、政府部門、社會團體等各類組織機構(gòu)。用于標(biāo)志證書持有人在進行信息交換、電子簽名、電子政務(wù)、電子商務(wù)等網(wǎng)絡(luò)活動中的身份,證書可存放在硬盤、USBKey、IC卡等各類介質(zhì)中。3.支付網(wǎng)關(guān)證書證書簽發(fā)中心針對支付網(wǎng)關(guān)簽發(fā)的數(shù)字證書,是支付網(wǎng)關(guān)實現(xiàn)數(shù)據(jù)加解密的主要工具,用于數(shù)字簽名和信息加密。支付網(wǎng)關(guān)證書僅用于支付網(wǎng)關(guān)提供的服務(wù)(Internet上各種安全協(xié)議與銀行現(xiàn)有網(wǎng)絡(luò)數(shù)據(jù)格式的轉(zhuǎn)換)。支付網(wǎng)關(guān)證書只能在有效狀態(tài)下使用且不可被申請者轉(zhuǎn)讓。支付網(wǎng)關(guān)(PaymentGateway)是銀行金融網(wǎng)絡(luò)系統(tǒng)和Internet網(wǎng)絡(luò)之間的接口,是由銀行操作的將Internet上傳輸?shù)臄?shù)據(jù)轉(zhuǎn)換為金融機構(gòu)內(nèi)部數(shù)據(jù)的一組服務(wù)器設(shè)備,或由指派的第三方處理商家的支付信息和顧客的支付指令。4.服務(wù)器證書組成Web服務(wù)器的SSL安全功能的唯一數(shù)字標(biāo)識。通過相互信任的第三方組織獲得,并為用戶提供驗證Web站點身份的手段。服務(wù)器證書包含詳細的身份驗證信息,如服務(wù)器內(nèi)容附屬的組織、頒發(fā)證書的組織以及稱為公鑰信息。服務(wù)器證書可以確保用戶關(guān)于web服務(wù)器內(nèi)容的驗證,而且建立的HTTP連接是安全的。5.企業(yè)或機構(gòu)代碼簽名證書代碼簽名證書是CA中心簽發(fā)給軟件提供商的數(shù)字證書,包含軟件提供商的身份信息、公鑰及CA的簽名。軟件提供商使用代碼簽名證書對軟件進行簽名后放到Internet上,當(dāng)用戶在Internet上下載該軟件時,將會得到提示,從而可以確信軟件的來源,以及軟件自簽名后到下載前,沒有遭到修改或破壞。代碼簽名證書可以對32位的.exe、.cab、.ocx和.class等程序和文件進行簽名。6.安全電子郵件證書在互聯(lián)網(wǎng)上發(fā)送電子郵件就像郵寄明信片一樣,很容易被別人隨意閱讀甚至篡改。使用安全電子郵件證書可以確保郵件的安全性。安全電子郵件證書可以安裝在標(biāo)準(zhǔn)的互聯(lián)網(wǎng)瀏覽器中,可以方便地應(yīng)用于NetscapeMessenger、MicrosoftOutlook、OutlookExpress等遵循安全電子郵件擴展協(xié)議的程序中。使用證書后,可以對電子郵件的內(nèi)容和附件進行加密,確保在傳輸?shù)倪^程中不被他人閱讀、截取和篡改。也可以對電子郵件進行簽名,使得接收方可以確認該電子郵件是由發(fā)送方發(fā)送的,并且在傳送過程中未被篡改。7.個人代碼簽名證書CA中心簽發(fā)給軟件提供人的數(shù)字證書,包含軟件提供個人的身份信息、公鑰及CA的簽名。軟件提供人使用代碼簽名證書對軟件進行簽名后放到Internet上,當(dāng)用戶在Internet上下載該軟件時,將會得到提示,從而可以確信:軟件的來源;以及軟件自簽名后到下載前,沒有遭到修改或破壞。代碼簽名證書可以對32位的.exe、.cab、.ocx、.class等程序和文件進行簽名。

9.2.3數(shù)字證書的授權(quán)機構(gòu)

數(shù)字證書由CA機構(gòu)(CertificateAuthority,證書授權(quán)中心)頒發(fā)。CA機構(gòu)作為電子商務(wù)交易中受信任的第三方,承擔(dān)公鑰體系中公鑰的合法性檢驗的責(zé)任。CA機構(gòu)簽發(fā)數(shù)字證書9.2.4部署基于數(shù)字證書的HTTPS網(wǎng)站HTTPS網(wǎng)站的流程的工作流程(1)HTTPS網(wǎng)站生成一個證書申請文件,并將其發(fā)送到CA機構(gòu)。(2)CA機構(gòu)為HTTPS網(wǎng)站生成一個根證書,其中包含與HTTPS網(wǎng)站進行通訊的公鑰。同時CA機構(gòu)為HTTPS網(wǎng)站頒發(fā)一個普通證書。普通證書繼承自根證書。(3)客戶端獲得HTTPS網(wǎng)站的根證書,并導(dǎo)入客戶端“根受信任的頒發(fā)者”列表。(4)客戶端訪問HTTPS網(wǎng)站時會獲得與其綁定的普通證書,并使用根證書對普通證書進行驗證,確定是否信任該網(wǎng)站。

IE瀏覽器在驗證證書的時候主要從下面3個方面檢查(1)證書的頒發(fā)者是否在“根受信任的證書頒發(fā)機構(gòu)列表”中;(2)證書是否過期;(3)證書的持有者是否和訪問的網(wǎng)站一致。1.在WindowsServer2003中IIS6.0在“控制面板”中點擊“添加或刪除程序”,打開“添加或刪除程序”窗口打開“Windows組件向?qū)А贝翱谶x擇應(yīng)用程序服務(wù)器組件的窗口IIS管理窗口2.配置和管理IIS設(shè)置網(wǎng)站的基本屬性設(shè)置網(wǎng)站的主目錄設(shè)置Web站點的默認文檔3.安裝證書服務(wù)在“添加或刪除程序”窗口中單擊左側(cè)的“添加/刪除Windows組件”圖標(biāo),打開“Windows組件向?qū)А贝翱?,選中“證書服務(wù)”,“選擇CA類型”窗口“選擇CA類型”窗口“選擇CA類型”窗口“是否停止Internet信息服務(wù)”對話框是否啟用ASP證書頒發(fā)機構(gòu)管理窗口設(shè)置證書頒發(fā)機構(gòu)的屬性

選擇對證書請求的處理策略4.創(chuàng)建請求證書文件默認網(wǎng)站屬性Web服務(wù)器證書向?qū)J網(wǎng)站屬性延遲或立即請求”對話框“名稱和安全性設(shè)置”窗口錄入單位信息窗口

“站點公用名稱”窗口“地理信息”窗口

“保存證書請求文件”窗口5.為Web站點申請CA證書安裝證書服務(wù)后,客戶端就可以通過訪問下面的地址申請證書了。http://網(wǎng)站IP地址/certsrv/選擇證書類型“高級證書申請”頁面提交一個證書申請或續(xù)訂申請“證書已頒發(fā)”頁面查看剛剛頒發(fā)的證書將證書保存為.cer文件6.將證書綁定到網(wǎng)站(1)依次選擇“控制面板”/“管理工具”/“IIS管理器”,打開IIS管理器。(2)右擊默認網(wǎng)站,選擇“屬性”,再選擇“目錄安全性”選項卡。如圖9.44所示。單擊“服務(wù)器證書”按鈕,打開Web服務(wù)器證書向?qū)?,如圖9.45所示。處理掛起的請求(3)單擊“下一步”按鈕,打開“掛起的證書請求”窗口,如圖9.46所示。(4)選擇“處理掛起的請求并安裝證書”,然后單擊“下一步”按鈕,打開“處理掛起的請求”窗口,如圖9.47所示。程序的運行結(jié)果(5)選擇前面申請到的證書文件c:\certnew.cer,然后單擊“下一步”按鈕,打開“為網(wǎng)站指定SSL端口”窗口。保持默認的443端口即可。(6)單擊“下一步”按鈕,打開“證書摘要”窗口??梢圆榭醋C書的摘要信息。單擊“下一步”按鈕,完成將證書綁定到網(wǎng)站的操作。7.啟用網(wǎng)站的HTTPS打開IIS管理器,右擊默認網(wǎng)站,選擇“屬性”,再選擇“目錄安全性”選項卡。然后單擊“編輯”按鈕,打開“安全通信”對話框通過HTTP方式已經(jīng)不能正常訪問HTTPS網(wǎng)站訪問HTTPS網(wǎng)站在創(chuàng)建請求證書文件時曾指定站點公用名稱,此時可以通過下面的url訪問HTTPS網(wǎng)站。https://站點公用名稱地址欄后面有一個小鎖頭圖標(biāo)表示該站點已經(jīng)啟用HTTPS9.3OpenSSL編程基礎(chǔ)9.3.1OpenSSL概況9.3.2需要包含的頭文件9.3.3需要引用的庫文件9.3.4初始化OpenSSL9.3.5創(chuàng)建SSL會話連接所使用的協(xié)議9.3.6加載和使用證書9.3.7SSL套接字9.3.8OpenSSL握手9.3.9通訊結(jié)束9.3.1OpenSSL概況OpenSSL是一個強大的、開源的安全套接字層密碼庫,它支持SSLv2/v3和TLS(TransportLayerSecurity,安全傳輸層協(xié)議)v1。OpenSSL基于EricA.Young和TimJ.Hudson開發(fā)的SSLeay庫。OpenSSL工具集遵循Apache風(fēng)格的許可協(xié)議。也就是說,用戶可以免費獲得、并將其應(yīng)用于商業(yè)或非商業(yè)應(yīng)用中。1.下載和安裝OpenSSLforWindows/products/Win32OpenSSL.htmlC:\OpenSSL-Win32目錄下包含的主要目錄bin,包含一些工具exe文件和dll文件。include,包含OpenSSL的頭文件(*.h文件)。lib,包含OpenSSL的庫文件(*.lib文件)。2.在VC++項目中引用OpenSSL首先在VisualStudio2012中選擇“文件”/“新建”/“項目”,打開“新建項目”對話框。在左側(cè)列表中依次選擇“模板”/“其他語言”/“VisualC++”,在項目類型列表中選擇“Win32控制臺應(yīng)用程序”,項目名輸入OpenSslServer,單擊“確定”按鈕創(chuàng)建項目。在菜單中選擇“項目”/“OpenSslServer屬性”,打開項目屬性對話框。在左側(cè)列表中選中“配置屬性”/“VC++目錄”,在“包含目錄”中增加C:\OpenSSL-Win32\include;,在“引用目錄”中增加C:\OpenSSL-Win32\lib;,在“庫目錄”中增加C:\OpenSSL-Win32\lib;配置VC++目錄9.3.2需要包含的頭文件要開發(fā)OpenSSL應(yīng)用程序,通常需要包含如下的頭文件#include"openssl/ssl.h"#include"openssl/x509.h"#include"openssl/rand.h"#include"openssl/err.h"9.3.3需要引用的庫文件要開發(fā)OpenSSL應(yīng)用程序,通常需要使用下面的語法引用庫文件#pragmacomment(lib,"libeay32.lib")#pragmacomment(lib,"ssleay32.lib")#pragmacomment(lib,"WS2_32.lib")libeay32.lib和ssleay32.lib保存在C:\OpenSSL-Win32\lib目錄下。WS2_32.lib一般由操作系統(tǒng)自帶。9.3.4初始化OpenSSL1.SSL_library_init()2.OpenSSL_add_all_algorithms()3.SSL_load_error_strings()9.3.5創(chuàng)建SSL會話連接所使用的協(xié)議服務(wù)器程序可以使用下面的語句指定SSL會話所使用的協(xié)議:SSL_METHOD*TLSv1_server_method(void);//使用TLSv1.0協(xié)議SSL_METHOD*SSLv2_server_method(void);//使用SSLv2協(xié)議SSL_METHOD*SSLv3_server_method(void);//使用SSLv3協(xié)議SSL_METHOD*SSLv23_server_method(void);//使用SSLv2/3協(xié)議客戶端程序可以使用下面的語句指定SSL會話所使用的協(xié)議:SSL_METHOD*TLSv1_client_method(void);//使用TLSv1.0協(xié)議SSL_METHOD*SSLv2_client_method(void);//使用SSLv2協(xié)議SSL_METHOD*SSLv3_client_method(void);//使用SSLv3協(xié)議SSL_METHOD*SSLv23_client_method(void);//使用SSLv2/v3協(xié)議9.3.6加載和使用證書1.設(shè)置證書驗證的方式2.加載證書3.加載私鑰文件1.設(shè)置證書驗證的方式可以調(diào)用SSL_CTX_set_verify()函數(shù)設(shè)置證書驗證的方式,函數(shù)原型如下:VoidSSL_CTX_set_verify(SSL_CTX*ctx,intmode,int(*verify_callback)(int,X509_STORE_CTX*));2.加載證書intSSL_CTX_load_verify_locations(SSL_CTX*ctx,constchar*CAfile,constchar*CApath);intSSL_CTX_use_certificate_file(SSL_CTX*ctx,constchar*file,inttype);3.加載私鑰文件intSSL_CTX_use_PrivateKey_file(SSL_CTX*ctx,constchar*file,inttype);intSSL_CTX_check_private_key(SSL_CTX*ctx)9.3.7SSL套接字1.SSL_new()2.SSL_set_rfd()1.SSL_new()SSL_new()函數(shù)用于申請一個SSL套接字,函數(shù)原型如下:SSL*SSL_new(SSL_CTX*ctx);參數(shù)ctx指定當(dāng)前的SSL連接環(huán)境(CTX)指針。如果操作成功則返回指向分配的SSL結(jié)構(gòu)體的指針;否則返回NULL。可以將分配的SSL結(jié)構(gòu)體綁定到一個套接字,從而得到SSL套接字。具體方法將在稍后介紹。2.SSL_set_rfd()SSL_set_rfd()函數(shù)用于綁定只讀套接字,函數(shù)原型如下:intSSL_set_rfd(SSL*ssl,intfd);參數(shù)說明如下:ssl,SSL結(jié)構(gòu)體指針。fd,綁定到ssl的只讀套接字句柄。如果操作成功則返回1;否則返回0。9.3.8OpenSSL握手1.SSL_connect()2.SSL_read()3.SSL_write()4.SSL_accept()1.SSL_connect()SSL_connect()函數(shù)用于初始化與TLS/SSL服務(wù)器的握手過程,也就是建立于TLS/SSL服務(wù)器的連接。SSL_connect()函數(shù)用于替代傳統(tǒng)的connect()函數(shù)。函數(shù)原型如下:intSSL_connect(SSL*ssl);參數(shù)ssl為SSL結(jié)構(gòu)體指針。如果操作成功則返回1;如果握手失敗,但是根據(jù)TLS/SSL協(xié)議關(guān)閉了Socket,則返回0。如果握手失敗,但是并沒有關(guān)閉Socket,則返回小于0的值。2.SSL_read()SSL_read()函數(shù)用于從TLS/SSL連接讀取字節(jié)。SSL_read()函數(shù)用于替代傳統(tǒng)的read()函數(shù)。函數(shù)原型如下:intSSL_read(SSL*ssl,void*buf,intnum);

參數(shù)說明如下:ssl,SSL結(jié)構(gòu)體指針。buf,用于接收數(shù)據(jù)的緩存區(qū)指針。num,指定讀取的字節(jié)數(shù)。如果操作成功則返回讀取的字節(jié)數(shù)。3.SSL_write()SSL_write()函數(shù)用于向TLS/SSL連接寫入字節(jié)。SSL_write()函數(shù)用于替代傳統(tǒng)的write()函數(shù)。函數(shù)原型如下:intSSL_write(SSL*ssl,constvoid*buf,intnum);參數(shù)說明如下:ssl,SSL結(jié)構(gòu)體指針。buf,發(fā)送數(shù)據(jù)的緩存區(qū)指針。num,指定發(fā)送的字節(jié)數(shù)。如果操作成功則返回讀取的字節(jié)數(shù)。4.SSL_accept()SSL_accept函數(shù)由服務(wù)器程序調(diào)用用于等待客戶端連接。SSL_accept()函數(shù)用于替代傳統(tǒng)的accept()函數(shù)。函數(shù)原型如下:intSSL_accept(SSL*ssl);參數(shù)ssl是SSL結(jié)構(gòu)體指針。SSL_accept()函數(shù)依賴底層的BIO結(jié)構(gòu)。BIO是抽象的IO接口,是覆蓋了許多類型I/O接口細節(jié)的一種應(yīng)用接口。9.3.9通訊結(jié)束1.SSL_shutdown()2.SSL_free()3.SSL_CTX_free()1.SSL_shutdown()SSL_shutdown()函數(shù)用于關(guān)閉一個TLS/SSL連接。函數(shù)原型如下:intSSL_shutdown(SSL*ssl);參數(shù)ssl是要關(guān)閉的SSL結(jié)構(gòu)體指針。如果操作成功,則SSL_shutdown()返回1。2.SSL_free()SSL_shutdown()函數(shù)用于釋放SSL套接字。函數(shù)原型如下:voidSSL_free(SSL*ssl);參數(shù)ssl是要釋放的SSL套接字。3.SSL_CTX_free()SSL_shutdown()函數(shù)用于釋放SSL環(huán)境。函數(shù)原型如下:voidSSL_free(SSL*ssl);參數(shù)ssl是要釋放的SSL環(huán)境。9.4OpenSSL編程實例9.4.1制作SSL證書9.4.2開發(fā)基于OpenSSL的服務(wù)器程序9.4.3開發(fā)基于OpenSSL的客戶端程序9.4.1制作SSL證書1.生成服務(wù)器端的私鑰文件2.生成服務(wù)器端的CSR文件3.生成CA證書4.生成客戶端的私鑰文件5.生成客戶端的CSR文件6.生成服務(wù)器端證書文件7.生成客戶端證書文件1.生成服務(wù)器端的私鑰文件使用openssl

genrsa命令可以生成rsa私鑰文件。這里執(zhí)行下面的命令:openssl

genrsa

-des3

-out

server.key

1024

參數(shù)-des3指定使用DES算法進行加密;參數(shù)-out指定輸出生成的私鑰文件是server.key。密鑰長度是1024bit。執(zhí)行命令后首先需要輸入并確認私鑰文件文件的密碼,這里假定為123456。以后在使用到私鑰文件server.key時需要使用該密碼。2.生成服務(wù)器端的CSR文件使用openssl

req命令可以生成證書請求,以讓CA來簽發(fā)、生成我們需要的證書。這里執(zhí)行下面的命令:openssl

req

-new

-key

server.key

-out

server.csr

-config

openssl.cfg

參數(shù)-new生成一個新的證書請求,并提示用戶輸入個人信息;參數(shù)-key指定使用的私鑰文件;參數(shù)-out指定輸出生成的CSR文件是server.csr。-config指定使用的配置文件。在有些版本的OpenSSL中,配置文件為f

。執(zhí)行命令后首先需要輸入私鑰文件server.key的密碼123456,輸入證書的身份信息CountryName(2lettercode)[AU]:CNStateorProvinceName(fullname)[Some-State]:BeijingLocalityName(eg,city)[]:BeijingOrganizationName(eg,company)[InternetWidgitsPtyLtd]:companyOrganizationalUnitName(eg,section)[]:departmentCommonName(e.g.serverFQDNorYOURname)[]:JohneyEmailAddress[]:my@

3.生成CA證書可以使用CA證書對CSR文件進行簽名,得到服務(wù)器證書和客戶端證書。因此需要首先生成CA證書。執(zhí)行下面的命令:opensslreq-new-x509-keyoutca.key-outca.crt-configopenssl.cfg命令可以生成一個私鑰文件ca.key和一個證書文件ca.crt。執(zhí)行命令后首先需要輸入私鑰文件ca.key的密碼0000,然后輸入證書的身份信息,這里假定與第2步中輸入的內(nèi)容完全相同。因為在使用CA證書對server.csr文件進行簽名時需要比對兩者中包含的身份信息。在有些版本的OpenSSL中,配置文件為f

。4.生成客戶端的私鑰文件使用openssl

genrsa命令可以生成rsa私鑰文件。這里執(zhí)行下面的命令:openssl

genrsa

-des3

-out

client.key

1024

執(zhí)行命令后首先需要輸入并確認私鑰文件文件的密碼,這里假定為123456。以后在使用到私鑰文件client.key時需要使用該密碼。5.生成客戶端的CSR文件執(zhí)行下面的命令:opensslreq-new-keyclient.key-outclient.csr-configopenssl.cfg

執(zhí)行命令后首先需要輸入私鑰文件client.key的密碼123456,然后輸入證書的身份信息,這里假定與第2步中輸入的內(nèi)容完全相同。6.生成服務(wù)器端證書文件可以使用CA證書對第2步中生成的server.csr文件進行簽名,得到服務(wù)器端證書文件server.crt。使用的命令如下:opensslca-inserver.csr-outserver.crt-certca.crt-keyfileca.key-configopenssl.cfg同樣,在有些版本的OpenSSL中,配置文件為f

。在執(zhí)行命令時需要首先輸入ca.key的密碼0000。錯誤解決方法如果有如下錯誤提示:

Iamunabletoaccessthe./demoCA/newcertsdirectory

./demoCA/newcerts:Nosuchfileordirectory解決方法如下:(1)在C:\OpenSSL-Win32\bin目錄下新建一個子目錄demoCA。(2)在demoCA目錄下新建一個子目錄newCerts。(3)在demoCA目錄中新建一空文件index.txt和serial文件(沒有后綴)。(4)以記事本方式打開serial文件,填入01這兩個數(shù)字,然后保存。7.生成客戶端證書文件生成客戶端證書文件的命令如下:opensslca-inclient.csr-outclient.crt-certca.crt-keyfileca.key-configopenssl.cfg在執(zhí)行命令時需要首先輸入ca.key的密碼0000。執(zhí)行命令的過程中,如果遇到錯誤,可以參照第6步中的方法解決。9.4.2開發(fā)基于OpenSSL的服務(wù)器程序1.本實例包含的頭文件2.本實例包含的庫文件3.定義常量4.初始化SSL環(huán)境5.加載服務(wù)器端證書6.正常的Socket通信7.SSL通信8.結(jié)束SSL通信,釋放資源1.本實例包含的頭文件#include<stdio.h>#include<conio.h>#include"stdafx.h"#include"afxdialogex.h"

#include<string.h>#include<iostream>#include<winsock2.h>#include"openssl/ssl.h"#include"openssl/x509.h"#include"openssl/rand.h"#include"openssl/err.h"2.本實例包含的庫文件#pragmacomment(lib,"libeay32.lib")#pragmacomment(lib,"ssleay32.lib")#pragmacomment(lib,"WS2_32.lib")3.定義常量#defineServerCertFile"server.crt"http://服務(wù)端的證書(需經(jīng)CA簽名)#defineServerKeyFile"server.key"http://服務(wù)端的私鑰(建議加密存儲)#defineCACertFile"ca.crt"http://CA的證書#definePort8989//準(zhǔn)備綁定的端口/*錯誤信息處理*/#defineCHK_NULL(param)if((param)==NULL){ERR_print_errors_fp(stdout);getchar();exit(1);}#defineCHK_ERR(err,msg)if((err)==-1){perror(msg);getchar();exit(1);}#defineCHK_SSL(err)if((err)==-1){ERR_print_errors_fp(stderr);exit(2);}

/*錯誤信息處理*/#defineCHK_NULL(param)if((param)==NULL){ERR_print_errors_fp(stdout);getchar();exit(1);}#defineCHK_ERR(err,msg)if((err)==-1){perror(msg);getchar();exit(1);}#defineCHK_SSL(err)if((err)==-1){ERR_print_errors_fp(stderr);getchar();exit(2);}4.初始化SSL環(huán)境WSADATAwsaData;if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){printf("WSAStartup()Failed:%d\n",GetLastError());return-1;}/*

初始化SSL環(huán)境;*/SSL_library_init();//SSL庫初始化,進行一些必要的初始化工作,用openssl編寫SSL/TLS程序時應(yīng)該首先調(diào)用此函數(shù);也可寫成OpenSSL_add_all_algorithms();即載入所有SSL算法,即SSleay_add_ssl_algorithms(),其實調(diào)用的仍是SSL_library_init();OpenSSL_add_ssl_algorithms();//對SSL進行初始化,其實調(diào)用intSSL_library_init(void),這是一個宏

SSL_load_error_strings();//加載SSL錯誤信息,為打印錯誤信息做準(zhǔn)備constSSL_METHOD*method=TLSv1_server_method();//服務(wù)器創(chuàng)建本次會話(通訊)所使用的協(xié)議:TLSv1協(xié)議方式;SSLv23_server_method()則是以SSLV2和V3標(biāo)準(zhǔn)兼容方式;sslCTX=SSL_CTX_new(method);//申請SSL會話的環(huán)境CTX(使用不同的協(xié)議進行會話,其環(huán)境也是不同的。);CHK_NULL(sslCTX);5.加載服務(wù)器端證書/*制定證書驗證方式:

根據(jù)需要設(shè)置CTX環(huán)境的屬性,一般是設(shè)置SSL握手階段證書的驗證方式:SSL_VERIFY_PEER表明要驗證對方,SSL_VERIFY_NONE(缺省)則表明需要驗證對方,

一般客戶端需要驗證服務(wù)器,而服務(wù)器無需驗證客戶端,當(dāng)然如果是相互認證,

則雙方都得驗證,如下:*/SSL_CTX_set_verify(sslCTX,SSL_VERIFY_PEER,NULL);//第三個參數(shù)是處理驗證的回調(diào)函數(shù),若無特殊需要,使用NULL即可;

/*加載CA證書:

為SSL會話環(huán)境加載CA證書:若要驗證,則需加載CA證書文件,第二參數(shù)為CA證書文件名,

第三參數(shù)為CA證書的路徑,如果第二個參數(shù)已經(jīng)給出的帶有相對路徑(當(dāng)前工程,或本應(yīng)用程序(*.exe)的同一目錄)或是絕對路徑,第三參數(shù)可設(shè)為NULL;*/SSL_CTX_load_verify_locations(sslCTX,CACertFile,NULL);接上/*為SSL會話加載用戶證書:

加載本地證書,第二參數(shù)為本地證書(server.crt)文件名,第三參數(shù)為證書文件的結(jié)構(gòu)類型:#defineX509_FILETYPE_PEM1#defineX509_FILETYPE_ASN12#defineX509_FILETYPE_DEFAULT3

失敗返回-1;5*/if(SSL_CTX_use_certificate_file(sslCTX,ServerCertFile,X509_FILETYPE_PEM)<=0){ ERR_print_errors_fp(stderr); getchar(); exit(3);}加載私鑰文件if(SSL_CTX_use_PrivateKey_file(sslCTX,ServerKeyFile,SSL_FILETYPE_PEM)<=0){ERR_print_errors_fp(stderr); getchar();exit(4);}

/*

加載了證書與私匙后,便可驗證證書與私匙是否相符;*/if(!SSL_CTX_check_private_key(sslCTX)){printf("Privatekeydoesnotmatchthecertificatepublickey\n");exit(5);設(shè)置加密列表/*設(shè)置加密列表:

根據(jù)SSL/TLS規(guī)范,,客戶端會提交一份自己能夠支持的加密方法的列表,

由服務(wù)端選擇一種方法后會通知客戶端,從而完成加密算法的協(xié)商.

如果不作任何指定,將選用DES-CBC3-SHA.用SSL_CTX_set_cipher_list可以指定自己希望用的

算法(實際上只是提高其優(yōu)先級,是否能使用還要看對方是否支持).

這里使用"RC4-MD5";即RC4做加密,MD5做消息摘要(先進行MD5運算,后進行RC4加密).*/SSL_CTX_set_cipher_list(sslCTX,"RC4-MD5");加載服務(wù)器端證書的過程(1)調(diào)用SSL_CTX_set_verify()函數(shù)設(shè)置證書驗證方式。參數(shù)SSL_VERIFY_PEER表示希望希望驗證對方的證書。(2)調(diào)用SSL_CTX_use_certificate_file()函數(shù)加載服務(wù)器端證書。注意,運行服務(wù)器程序之前,需要將ca.crt,server.crt,server.key三個文件復(fù)制到本實例的可執(zhí)行文件目錄下,以便程序可以找到它們。(3)調(diào)用CTX_use_PrivateKey_file()函數(shù)加載服務(wù)器端私鑰文件server.key。程序運行到此處會要求用戶輸入server.key的密碼123456。(4)調(diào)用SSL_CTX_check_private_key()函數(shù)驗證證書與私匙是否相符。(5)調(diào)用SSL_CTX_set_cipher_list()函數(shù)設(shè)置證書驗證方式。6.正常的Socket通信/*現(xiàn)在開始正常的TCPSocket過程*/printf("ServerbeginTCPsocket...\n");

//創(chuàng)建一個普通的SocketintlistenSocket=socket(AF_INET,SOCK_STREAM,0);CHK_ERR(listenSocket,"SocketcreatedFailed!");

structsockaddr_inserverAddr;memset(&serverAddr,0,sizeof(serverAddr));serverAddr.sin_family=AF_INET;serverAddr.sin_addr.s_addr=INADDR_ANY;serverAddr.sin_port=htons(Port);//將本地地址與Socket綁定在一起errRes=bind(listenSocket,(structsockaddr*)&serverAddr,sizeof(serverAddr));CHK_ERR(errRes,"BindFailed!");//將套接字設(shè)置為監(jiān)聽接入連接的狀態(tài)errRes=listen(listenSocket,5);//第二參數(shù)為最大等待連接數(shù),1--5之間;CHK_ERR(errRes,"ListenFailed!");

接上structsockaddr_inclientAddr;intclientAddrLen=sizeof(clientAddr);//將套接字設(shè)置為監(jiān)聽接入連接的狀態(tài)connectSocket=accept(listenSocket,(sockaddr*)&clientAddr,&clientAddrLen);//此socket:connectSocket可用來在服務(wù)端和客戶端之間的傳遞信息;CHK_ERR(connectSocket,"AcceptFailed!");closesocket(listenSocket);//關(guān)閉服務(wù)端的socket,不再連接新的客戶端;(在多線程服務(wù)端,不關(guān)閉此偵聽socket)

printf("Connectionfrom%lx,port%x\n",clientAddr.sin_addr.s_addr,clientAddr.sin_port);7.SSL通信printf("BeginserversideSSLnegotiation...\n");//建立SSL套接字:SSL套接字是建立在普通的TCP套接字基礎(chǔ)之上;sslSocket=SSL_new(sslCTX);//申請一個SSL套接字;CHK_NULL(sslSocket);

SSL_set_fd(sslSocket,connectSocket);//綁定讀寫套接字;SSL_set_rfd()只讀;SSL_set_wfd(SSL*ssl,intfd)只寫;errRes=SSL_accept(sslSocket);//完成握手過程;客戶端使用SSL_connect(SSL*ssl),服務(wù)端使用SSL_accept(SSL*ssl);printf("SSL_acceptfinished!\n");CHK_SSL(errRes);

//打印所有加密算法的信息(可選);printf("SSLconnectionusing%s\n",SSL_get_cipher(sslSocket));

/*握手過程完成之后,通常需要詢問通信雙方的證書信息,以便進行相應(yīng)的驗證*/X509*X509_ClientCert=SSL_get_peer_certificate(sslSocket);//SSL套接字中提取對方的證書信息整理成X509對象,這些信息已經(jīng)被SSL驗證過了;if(X509_ClientCert!=NULL){printf("Clientcertificate:\n");

接上//X509_NAME_oneline()將對象變成字符型,以便打印出來,下同;char*subjectName=X509_NAME_oneline(X509_get_subject_name(X509_ClientCert),0,0);//X509_get_subject_name(client_cert)得到證書所有者的名字;CHK_NULL(subjectName);printf("\tsubject:%s\n",subjectName);

char*issuerName=X509_NAME_oneline(X509_get_issuer_name(X509_ClientCert),0,0);//X509_get_issuer_name(X509_ClientCert)得到證書簽署者(往往是CA)的名字,參數(shù)可用通過SSL_get_peer_certificate()得到的X509對象;CHK_NULL(issuerName);printf("\tissuer:%s\n",issuerName);

接上//驗證完成后,可以將證書釋放,因為已經(jīng)通過驗證了,下面要做的事就是SSL通信了;X509_free(X509_ClientCert);//如不再需要,需將證書釋放;}else{printf("Clientdoesnothavecertificate!\n");}

/*開始SSL通信:

當(dāng)SSL握手完成之后,就可以進行安全的數(shù)據(jù)傳輸了,在數(shù)據(jù)傳輸階段,

需要使用SSL_read()和SSL_write()來替代傳統(tǒng)的read()和write()函數(shù),來完成對套接字的讀寫操作:*/printf("BeginSSLdataexchange...\n");charbuffer[4096]={};intres=SSL_read(sslSocket,buffer,sizeof(buffer)/sizeof(char)-1);CHK_SSL(res);buffer[res]='\0';printf("Recv%dcharacters:'%s'\n",res,buffer);

res=SSL_write(sslSocket,"ServerSay:Ihearyou,client!",strlen("ServerSay:Ihearyou,client!"));CHK_SSL(res);SSL通信的過程(1)調(diào)用SSL_new()函數(shù)申請一個SSL套接字sslSocket。(2)調(diào)用SSL_set_fd()函數(shù)將SSL套接字sslSocket綁定到讀寫套接字connectSocket。(3)調(diào)用SSL_accept()函數(shù)等待客戶端連接。(4)調(diào)用SSL_get_peer_certificate()函數(shù)從SSL套接字中提取對方的證書信息,然后打印證書信息。(5)調(diào)用X509_get_issuer_name()函數(shù)得到客戶端證書的簽署者,然后將其打印。(6)調(diào)用X509_free()函數(shù)將證書釋放。(7)調(diào)用SSL_read()函數(shù)讀取來自客戶端的數(shù)據(jù),然后將其打印。(8)調(diào)用SSL_write()函數(shù)向客戶端發(fā)送數(shù)據(jù)“ServerSay:Ihearyou,client!”。8.結(jié)束SSL通信,釋放資源res=SSL_shutdown(sslSocket);//通知關(guān)閉SSL套接字,一般第一次res==0,當(dāng)單向關(guān)閉時只須關(guān)閉這一次即可;if(!res)//再次調(diào)用關(guān)閉(雙向關(guān)閉時須再次調(diào)用);{shutdown(connectSocket,1);res=SSL_shutdown(sslSocket);}switch(res){case1:break;case0:case-1:default:perror("Shutdownfailed!");exit(-1);}

接上SSL_free(sslSocket);//釋放SSL套接字;SSL_CTX_free(sslCTX);//釋放SSL會話環(huán)境;WSACleanup();//結(jié)束WindowsSocketsDLL的使用。

getchar();//暫停,等待用戶輸入 return0;服務(wù)器程序的運行界面9.4.3開發(fā)基于OpenSSL的客戶端程序1.定義常量2.初始化SSL環(huán)境3.加載客戶端證書4.正常的Socket通信5.SSL通信6.結(jié)束SSL通信,釋放資源1.定義常量#defineClientCertFile"client.crt"http://客戶端的證書(需經(jīng)CA簽名);#defineClientKeyFile"client.key"http://客戶端的私鑰(建議加密存儲);#defineCACertFile"ca.crt"http://CA的證書;#definePort8989//服務(wù)端的端口;#defineServerAddress""http://服務(wù)端的IP地址;2.初始化SSL環(huán)境下面的代碼都定義在主函數(shù)_tmain()函數(shù)中。初始化SSL環(huán)境的代碼與服務(wù)器程序相同,請參照9.4.2小節(jié)理解。3.加載客戶端證書//制定證書驗證方式;SSL_CTX_set_verify(sslCTX,SSL_VERIFY_PEER,NULL);//加載CA證書;SSL_CTX_load_verify_locations(sslCTX,CACertFile,NULL);

//為SSL會話加載用戶(client.crt)證書;if(SSL_CTX_use_certificate_file(sslCTX,ClientCertFile,SSL_FILETYPE_PEM)<=0){ERR_print_errors_fp(stderr);exit(-2);}

接上//為SSL會話加載用戶私鑰(client.key);if(SSL_CTX_use_PrivateKey_file(sslCTX,ClientKeyFile,SSL_FILETYPE_PEM)<=0){ERR_print_errors_fp(stderr);getchar();exit(-3);}

//驗證證書與私匙是否相符;if(!SSL_CTX_check_private_key(sslCTX)){printf("Privatekeydoesnotmatchthecertificatepublickey!\n");getchar();exit(-4);}加載服務(wù)器端證書的過程(1)調(diào)用SSL_CTX_set_verify()函數(shù)設(shè)置證書驗證方式。參數(shù)SSL_VERIFY_PEER表示希望希望驗證對方的證書。(2)調(diào)用SSL_CTX_use_certificate_file函數(shù)加載客戶端證書。注意,運行客戶端程序之前,需要將ca.crt,client.crt,client.key三個文件復(fù)制到本實例的可執(zhí)行文件目錄下,以便程序可以找到它們。(3)調(diào)用CTX_use_PrivateKey_file()函數(shù)加載服務(wù)器端私鑰文件client.key。程序運行到此處會要求用戶輸入client.key的密碼123456。(4)調(diào)用SSL_CTX_check_private_key()函數(shù)驗證證書與私匙是否相符。(5)調(diào)用SSL_CTX_set_cipher_list()函數(shù)設(shè)置證書驗證方式。4.正常的Socket通信//構(gòu)建隨機數(shù)生成機制,WIN32平臺必需:srand((unsigned)time(NULL));intseed_int[100];//存放隨機序列for(inti=0;i<100;i++){seed_int[i]=rand();}RAND_seed(seed_int,sizeof(seed_int)/sizeof(int));

/*現(xiàn)在開始正常的TCPS

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論