基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第1頁
基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第2頁
基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第3頁
基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第4頁
基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)摘要:隨著網(wǎng)絡(luò)技術(shù)的快速發(fā)展,使我們的生活豐富多彩,工作的效率也提高了不少。盡管網(wǎng)絡(luò)的出現(xiàn)給我們帶來了很多的福利和方便,但網(wǎng)絡(luò)安全問題也在時(shí)時(shí)困擾著我們,病毒、黑客的侵犯,各種威脅之聲的不斷傳出,網(wǎng)絡(luò)安全問題也就成為了社會(huì)關(guān)注的重點(diǎn)問題。文件的安全就是安全問題之一,文件可能會(huì)包含了很多的機(jī)密,一旦被黑客竊取,那損失是不可想象的。所以下面我們簡單的談?wù)勎募咏饷艿南嚓P(guān)算法。因?yàn)檫^于復(fù)雜的加密算法實(shí)現(xiàn)起來非常困難,所以在過去,許多應(yīng)用程序只能使用非常簡單的加密技術(shù),這樣做的結(jié)果就是加密的數(shù)據(jù)很容易就可以被人破譯。而使用Microsoft提供的加密應(yīng)

2、用程序接口(即Cryptography API),或稱CryptoAPI,就可以方便地在應(yīng)用程序中加入強(qiáng)大的加密功能,而不必考慮基本的算法。我們利用CryptoAPI來實(shí)現(xiàn)對(duì)文件的加密和解密。關(guān)鍵詞:文件的加解密,CryptoAPI。1、 設(shè)計(jì)要求與實(shí)現(xiàn):基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)2、 設(shè)計(jì)環(huán)境與工具1 軟件環(huán)境、工具Windows 8.1 、visual studio 20122 CryptoAPI加密服務(wù)提供者CSP加密服務(wù)相關(guān)的所有操作都在CSP實(shí)現(xiàn),它是真正實(shí)現(xiàn)加密相關(guān)服務(wù)的獨(dú)立模塊,既可以由軟件實(shí)現(xiàn)也可以由硬件實(shí)現(xiàn)。每個(gè)CSP必須包含一個(gè)動(dòng)態(tài)鏈接庫和一個(gè)簽名文

3、件,簽名文件用于保證底層CSP的安全性,CryptoAPI接口在加載每個(gè)CSP時(shí),需要驗(yàn)證CSP的簽名,如果簽名無效,則拒絕加載,CSP的簽名由微軟公司簽發(fā)。同時(shí),每個(gè)CSP都有一個(gè)名字和一個(gè)類型,名字必須是唯一的,這樣便于CryptoAPI找到對(duì)應(yīng)的CSP。CSP是真正實(shí)行加密的獨(dú)立模塊,可以由軟件實(shí)現(xiàn)也可以由硬件實(shí)現(xiàn)。CSP必須符合CryptoAPI接口規(guī)范。每個(gè)CSP有一個(gè)密鑰庫,密鑰庫用于存儲(chǔ)密鑰。每個(gè)密鑰庫包括一個(gè)或多個(gè)密鑰容器(Key Containers)。每個(gè)密鑰容器中包含屬于一個(gè)特定用戶的所有密鑰對(duì)。每個(gè)密鑰容器被賦予一個(gè)唯一的名字。在銷毀密鑰容器前,CSP將永久保存每一個(gè)密

4、鑰容器,包括保存每個(gè)密鑰容器中的公/私鑰對(duì)。每個(gè)CSP都有一個(gè)名字和一個(gè)類型。每個(gè)CSP的名字是唯一的,這樣便于CryptoAPI找到對(duì)應(yīng)的CSP。目前已經(jīng)有9種CSP類型,并且還在增長。下表列出它們支持的密鑰交換算法、簽名算法、對(duì)稱加密算法和Hash算法。二、詳細(xì)設(shè)計(jì)(1)原理概述CryptoAPI是一組函數(shù),為了完成數(shù)學(xué)計(jì)算,必須具有密碼服務(wù)提供者模塊(CSP)。Microsoft通過捆綁RSA Base Provider在操作系統(tǒng)級(jí)提供一個(gè)CSP,使用RSA公司的公鑰加密算法,更多的CSP可以根據(jù)需要增加到應(yīng)用中。事實(shí)上,CSP有可能與特殊硬件設(shè)備(如智能卡)一起來進(jìn)行數(shù)據(jù)加密。Cryp

5、toAPI接口允許簡單的函數(shù)調(diào)用來加密數(shù)據(jù),交換公鑰,散列一個(gè)消息來建立摘要以及生成數(shù)字簽名。它還提供高級(jí)的管理操作,如從一組可能的CSP中使用一個(gè)CSP。此外,CryptoAPI還為許多高級(jí)安全性服務(wù)提供了基礎(chǔ),包括用于電子商務(wù)的SET,用于加密客戶機(jī)/服務(wù)器消息的PCT,用于在各個(gè)平臺(tái)之間來回傳遞機(jī)密數(shù)據(jù)和密鑰的PFX,代碼簽名等等。數(shù)據(jù)加解密,程序分為四大主要部分:1、 獲取CSP句柄:真正實(shí)現(xiàn)加密相關(guān)服務(wù)的獨(dú)立模塊。2、 獲取加密密鑰:進(jìn)行加、解密,必然需要構(gòu)造密鑰。 兩種方法:通過哈希值構(gòu)造通過隨機(jī)數(shù)構(gòu)造。3、 數(shù)據(jù)加密與解密:實(shí)現(xiàn)對(duì)數(shù)據(jù)進(jìn)行加密解密操作。4、 相關(guān)資源釋放:釋放申請(qǐng)

6、的相關(guān)資源。 (下圖為數(shù)據(jù)加解密的流程) (參考網(wǎng)絡(luò)安全程序設(shè)計(jì)教程李紅嬌著) (2) CryptoAPI應(yīng)用程序的編譯環(huán)境包含的頭文件 #include <windows.h> #include <wincrypt.h>包含的靜態(tài)鏈接庫鏈接CryptoAPI函數(shù)必須有靜態(tài)庫Crypto32.lib的支持,部分CryptoAPI函數(shù)可能還需要靜態(tài)庫advapi32.lib及CryptUI.lib的支持。若在VC+6.0和VS2012上編譯程序,則需加上以下語句# ifndef _WIN32_WINNT# define _WIN32_WINNT 0x0400# endif

7、(3)實(shí)驗(yàn)步驟1) 在VS2012下實(shí)現(xiàn)基于CryptoAPI的文件加密。 a、創(chuàng)建會(huì)話密鑰 為保證數(shù)據(jù)加密效率,CryptoAPI規(guī)定數(shù)據(jù)加密操作必須基于對(duì)稱密碼進(jìn)行。于是,加密方進(jìn)行加密操作首先必須創(chuàng)建會(huì)話密鑰,一般可以通過調(diào)用函數(shù)CryptoGenKey或CryptDeriveKey創(chuàng)建,在創(chuàng)建會(huì)話密鑰時(shí)指定加密算法。b、加密數(shù)據(jù) 在創(chuàng)建會(huì)話密鑰后,則可以調(diào)用CryptEncrypt函數(shù)進(jìn)行加密操作。加密操作需要注意的是每次加密數(shù)據(jù)塊的長度必須根據(jù)具體的算法和算法類型確定,一般來說,加密數(shù)據(jù)塊長度為算法規(guī)定的基準(zhǔn)加密塊長度的整數(shù)倍。對(duì)于分組密碼,需為密文數(shù)據(jù)

8、塊預(yù)留一個(gè)基準(zhǔn)塊長度的空間。c、安全保存或交換會(huì)話密鑰數(shù)據(jù)加密完成后,當(dāng)在今后的某個(gè)時(shí)間或其他用戶需要解密數(shù)據(jù)時(shí),必須保存會(huì)話密鑰以備后用,或者是傳輸會(huì)話密鑰給特定用戶以使其能正確進(jìn)行解密操作。2) 在VS2012下實(shí)現(xiàn)基于CryptoAPI的文件解密。 a、獲取會(huì)話密鑰 根據(jù)保存或傳輸會(huì)話密鑰方式不同,進(jìn)行相應(yīng)的操作正確獲取會(huì)話密鑰b、解密數(shù)據(jù)利用獲取的會(huì)話密鑰調(diào)用函數(shù)CryptDecrypt解密數(shù)據(jù),它和函數(shù)CryptEncrypt互為逆操作。同樣的,解密操作需要注意的是每次解密數(shù)據(jù)塊的長度必須根據(jù)具體的算法和算法類型確定,一般來說,解密數(shù)據(jù)塊長度為算法基準(zhǔn)加

9、密塊長度的整數(shù)倍。要求: 1) 算法的詳細(xì)實(shí)現(xiàn)過程。 a) 獲得csp句柄 b) 構(gòu)造密鑰 c) 數(shù)據(jù)加密 d) 數(shù)據(jù)解密e) 釋放相關(guān)資源 2)  算法實(shí)現(xiàn)的流程圖 三、實(shí)驗(yàn)結(jié)果原文件加密后解密后PS:我們?cè)诩用艿臅r(shí)候,沒有采用通過隨機(jī)數(shù)創(chuàng)建密鑰,然后只能通過輸入密碼創(chuàng)建加密密鑰。截圖:未加密四、設(shè)計(jì)總結(jié)由于多方嘗試并編寫Openssl對(duì)文件的加解密方法,均以失敗告終,所以我們小組決定采用新的加密算法,即Windows CryptoAPI,由微軟公司提出

10、的一種安全加密應(yīng)用服務(wù)框架。本次試驗(yàn)的主要內(nèi)容是基于CryptoAPI的文件加解密系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn),在仔細(xì)看懂代碼的基礎(chǔ)上,真正明白了CryptoAPI的結(jié)構(gòu)體系。在加密操作時(shí),首先要?jiǎng)?chuàng)建會(huì)話密鑰,在創(chuàng)建會(huì)話密鑰時(shí)指定加密算法,注意的是,創(chuàng)建會(huì)話密鑰時(shí),它制定具體的加密算法應(yīng)該注意具體的CSP是否支持此算法。我們?cè)谧黾用艿臅r(shí)候,沒有加入通過隨機(jī)數(shù)創(chuàng)建會(huì)話密鑰,只能進(jìn)行輸入密碼創(chuàng)建加密密鑰。然后是進(jìn)行數(shù)據(jù)的加密操作,當(dāng)完成以后要進(jìn)行安全保存或者交換會(huì)話密鑰。解密時(shí)要獲取會(huì)話密鑰,然后進(jìn)行數(shù)據(jù)解密。CryptoAPI除直接用于加密數(shù)據(jù)外,還為許多高級(jí)安全性服務(wù)提供了基礎(chǔ),包括用于電子商務(wù)的SET,

11、用于加密客戶機(jī)/服務(wù)器消息的PCT,用于在各個(gè)平臺(tái)之間來回傳遞機(jī)密數(shù)據(jù)和密鑰的PFX,代碼簽名等等。通過此次編寫程序,我對(duì)基于CryptoAPI的文件加解密系統(tǒng)有了更深層次的了解,對(duì)之前做過的基于CryptoAPI 實(shí)現(xiàn)文件完整性校驗(yàn)的實(shí)驗(yàn)理解的更加透徹。在編寫程序的過程中,遇到了很多棘手的問題,但是這些問題,我通過了找老師,上網(wǎng)查詢問題出錯(cuò)的原因等方法努力的尋求答案,到現(xiàn)在為止,程序已經(jīng)順利完成,運(yùn)行無阻。自己根據(jù)要求,從零開始做一份實(shí)驗(yàn)真的不容易,需要對(duì)整體結(jié)構(gòu)局勢(shì)進(jìn)行把握,在做之前要做好多重準(zhǔn)備工作,例如運(yùn)行環(huán)境(軟、硬件環(huán)境)、輸入的形式和輸入值的范圍、輸出的形式描述、功能描述。細(xì)節(jié)決

12、定成敗,對(duì)于我而言,這次的作業(yè)讓我清楚認(rèn)識(shí)到,注重細(xì)節(jié)的重要性,有時(shí)候一個(gè)字母的大小寫,幾個(gè)變量的數(shù)據(jù)類型的統(tǒng)一性,考慮后選擇的更為合適的數(shù)據(jù)類型,重復(fù)執(zhí)行的問題等等,這些都讓我不斷進(jìn)步。5、 源代碼加密:#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400#endif #include <stdio.h>#include <string.h>#include <iostream>#include <conio.h>#include <windows.h>#include <wincry

13、pt.h>#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)#define KEYLENGTH 0x00800000#define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 class Encpublic:HCRYPTPROV GetCryptProv();BOOL EncryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword); HCRYPTKEY GenKeyByP

14、assword(HCRYPTPROV hCryptProv,PCHAR szPassword);#include<iostream>#include "Enc.h"using namespace std;/ 功能:加密原文szSource文件,加密后的數(shù)據(jù)存儲(chǔ)在szDestination文件中/ 參數(shù):/ szSource:原文文件名/ szDestination:加密后數(shù)據(jù)存儲(chǔ)文件/ szPassword:用戶輸入的密碼 BOOL Enc:EncryptFile( PCHAR szSource, PCHAR szDestination, PCHAR szPas

15、sword) / 變量申明與初始化.FILE *hSource; FILE *hDestination; HCRYPTPROV hCryptProv; HCRYPTKEY hKey; PBYTE pbBuffer; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; / 打開原文文件. if(hSource = fopen(szSource,"rb") cout<<"原文文件"<<szSource<<"已經(jīng)打開. n"else cout<&l

16、t;"打開原文文件出錯(cuò)!"<<endl; / 打開目標(biāo)文件. if(hDestination = fopen(szDestination,"wb") cout<<"目標(biāo)文件"<<szDestination<<"已經(jīng)打開. n"<<endl;elsecout<<"打開目標(biāo)文件出錯(cuò)!"<<endl; /獲取加密服務(wù)者句柄hCryptProv = GetCryptProv();/ 創(chuàng)建會(huì)話密鑰.if(!szPasswo

17、rd | strcmp(szPassword,"")=0 ) /hKey = GenKeyByRandom( hCryptProv, hDestination);當(dāng)輸入密碼為空時(shí),則創(chuàng)建隨機(jī)的加密密鑰,并導(dǎo)出創(chuàng)建的密鑰保存到文件中.cout<<"你輸入的密鑰為空!請(qǐng)正確輸入!"<<endl; else / 當(dāng)輸入密碼不為空時(shí),則通過輸入密碼創(chuàng)建加密密鑰hKey=GenKeyByPassword( hCryptProv, szPassword); / 因?yàn)榧用芩惴ò碋NCRYPT_BLOCK_SIZE 大小塊加密,所以被加密的/ 數(shù)

18、據(jù)長度必須是ENCRYPT_BLOCK_SIZE 的整數(shù)倍。下面計(jì)算一次加密的/ 數(shù)據(jù)長度。dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; / 確定加密后密文數(shù)據(jù)塊大小. 若是分組密碼模式,則必須有容納額外塊的空間if(ENCRYPT_BLOCK_SIZE > 1) dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; else dwBufferLen = dwBlockLen; / 分配內(nèi)存空間. if(pbBuffer = (BYTE *)malloc(dwBufferLen)cout<<

19、;"已經(jīng)為緩沖區(qū)分配了內(nèi)存. n"else cout<<"所需內(nèi)存不夠. n" / 循環(huán)加密 原文件do / 每次從原文件中讀取dwBlockLen字節(jié)數(shù)據(jù). dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); if(ferror(hSource) cout<<"讀取明文文件出錯(cuò)!n"/-/ 加密數(shù)據(jù). if(!CryptEncrypt(hKey,/密鑰0,/如果數(shù)據(jù)同時(shí)進(jìn)行散列和加密,這里傳入一個(gè)散列對(duì)象feof(hSource),/如果是最后一個(gè)被加密的塊,

20、輸入TRUE.如果不是輸入FALSE./這里通過判斷是否到文件尾來決定是否為最后一塊。0,/保留pbBuffer,/輸入被加密數(shù)據(jù),輸出加密后的數(shù)據(jù)&dwCount,/輸入被加密數(shù)據(jù)實(shí)際長度,輸出加密后數(shù)據(jù)長度dwBufferLen)/pbBuffer的大小。 cout<<"加密數(shù)據(jù)時(shí)出錯(cuò). n" /-/ 把加密后數(shù)據(jù)寫到密文文件中 fwrite(pbBuffer, 1, dwCount, hDestination); if(ferror(hDestination) cout<<"寫入密文時(shí)出錯(cuò)." while(!feof

21、(hSource); /-/ 關(guān)閉文件if(hSource)if(fclose(hSource)cout<<"關(guān)閉原文文件出錯(cuò)!"if(hDestination)if(fclose(hDestination)cout<<"關(guān)閉目標(biāo)文件出錯(cuò)!"/-/ 釋放內(nèi)存空間. if(pbBuffer) free(pbBuffer); /-/ 銷毀會(huì)話密鑰if(hKey)if(!(CryptDestroyKey(hKey)cout<<"銷毀會(huì)話密鑰時(shí)出錯(cuò)"<<endl;/-/ 釋放CSP句柄if(hC

22、ryptProv)if(!(CryptReleaseContext(hCryptProv, 0)cout<<"釋放CSP句柄時(shí)出錯(cuò)"<<endl;return(TRUE); / end Encryptfile/獲取加密提供者句柄HCRYPTPROV Enc:GetCryptProv()HCRYPTPROV hCryptProv; / 加密服務(wù)提供者句柄/獲取加密提供者句柄if(CryptAcquireContext(&hCryptProv, / 加密服務(wù)提供者句柄NULL, / 密鑰容器名,這里使用登陸用戶名MS_ENHANCED_PROV,

23、 / 加密服務(wù)提供者 PROV_RSA_FULL, / 加密服務(wù)提供者類型,可以提供加密和簽名等功能0) / 標(biāo)志cout<<"加密服務(wù)提供者句柄獲取成功!n"else/重新建立一個(gè)新的密鑰集 if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) cout<<"重新建立一個(gè)新的密鑰集出錯(cuò)!"return hCryptProv;/ GenKeyByRandom:通過輸入密碼創(chuàng)建會(huì)話密鑰/ 參數(shù):

24、hCryptProv CSP句柄/ szPassword 輸入密碼HCRYPTKEY Enc:GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword)HCRYPTKEY hKey; HCRYPTHASH hHash;/-/ 創(chuàng)建哈希句柄. if(CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash)cout<<"一個(gè)哈希句柄已經(jīng)被創(chuàng)建. n"else cout<<"Error during CryptCreateHash!n&q

25、uot; /-/ 計(jì)算輸入密碼的哈希值. if(CryptHashData( hHash, (BYTE *)szPassword, strlen(szPassword), 0) cout<<"密碼已經(jīng)被添加到了哈希表中. n" else cout<<"計(jì)算輸入密碼的哈希值時(shí)出錯(cuò). n" /-/ 通過哈希值創(chuàng)建會(huì)話密鑰. if(CryptDeriveKey( hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey) cout<<"通過密碼的哈希值獲得

26、了加密密鑰. n" else cout<<"Error during CryptDeriveKey!n" /-/ 銷毀哈希句柄. if(hHash) if(!(CryptDestroyHash(hHash) cout<<"Error during CryptDestroyHash"<<endl; hHash = 0;/返回創(chuàng)建的會(huì)話密鑰return hKey;解密:#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400#endif #include <stdio.

27、h>#include <string.h>#include <conio.h>#include <windows.h>#include <wincrypt.h>#include <iostream>#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)#define KEYLENGTH 0x00800000#define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 class Dec

28、/加密文件的方法public:HCRYPTPROV GetCryptProv(); /方法的原型BOOL DecryptFile( PCHAR szSource, PCHAR szDestination, CHAR *szPassword); HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword); /通過輸入口令創(chuàng)建會(huì)話密鑰,我們的密碼HCRYPTKEY GenKeyFromFile(HCRYPTPROV hCryptProv,FILE* hSource);#ifndef _WIN32_WINNT#define _

29、WIN32_WINNT 0x0400#endif #include <stdio.h>#include <string.h>#include <conio.h>#include <windows.h>#include <wincrypt.h>#include <iostream>#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)#define KEYLENGTH 0x00800000#define ENCRYPT_ALGORITHM CALG

30、_RC4 #define ENCRYPT_BLOCK_SIZE 8 #include <iostream>#include "Dec.h"using namespace std;/*功能:解密密文szSource文件,解密后的數(shù)據(jù)存儲(chǔ)到szDestination文件中*/BOOL Dec:DecryptFile( PCHAR szSource, /密文文件名 PCHAR szDestination, /解密后數(shù)據(jù)存儲(chǔ)文件 PCHAR szPassword) /口令,即密碼,其實(shí)口令和密碼是兩回事,了解一下就行了,作用一樣 /-/ 局部變量申明與初始化.FILE

31、*hSource; FILE *hDestination; HCRYPTPROV hCryptProv; HCRYPTKEY hKey; PBYTE pbBuffer; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; BOOL status = FALSE; /-/ 打開密文文件. if(!(hSource = fopen(szSource,"rb") cout<<"打開密文文件出錯(cuò)!"<<endl;/-/ 打開目標(biāo)文件,用于存儲(chǔ)解密后的數(shù)據(jù). if(!(hDestinati

32、on = fopen(szDestination,"wb")cout<<"打開明文文件出錯(cuò)!"<<endl;/獲取加密服務(wù)者句柄hCryptProv = GetCryptProv();/獲取或創(chuàng)建會(huì)話密鑰if(!szPassword| strcmp(szPassword,"")=0 ) /-/從密文文件導(dǎo)入保存的會(huì)話密鑰 hKey = GenKeyFromFile( hCryptProv,hSource); else /-/ 通過輸入密碼重新創(chuàng)建會(huì)話密鑰. hKey=GenKeyByPassword( hCry

33、ptProv, szPassword); / 計(jì)算一次解密的數(shù)據(jù)長度,它是ENCRYPT_BLOCK_SIZE 的整數(shù)倍dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; dwBufferLen = dwBlockLen; /-/ 分配內(nèi)存空間. if(!(pbBuffer = (BYTE *)malloc(dwBufferLen) cout<<"所需內(nèi)存不夠!"<<endl; /-/ 解密密文文件,解密后數(shù)據(jù)保存在目標(biāo)文件 do /-/ 每次從密文文件中讀取dwBlockLen字節(jié)數(shù)據(jù). dwCount =

34、 fread( pbBuffer, 1, dwBlockLen, hSource); if(ferror(hSource)cout<<"讀取密文文件出錯(cuò)!"<<endl;/-/ 解密 數(shù)據(jù)if(!CryptDecrypt( hKey, 0, feof(hSource), 0, pbBuffer, &dwCount) cout<<"解密數(shù)據(jù)時(shí)出錯(cuò)!"<<endl; /-/ 把解密后的數(shù)據(jù)寫入目標(biāo)文件中. fwrite(pbBuffer, 1, dwCount, hDestination); if(fe

35、rror(hDestination) cout<<"把解密后的數(shù)據(jù)寫入目標(biāo)文件中時(shí)出錯(cuò)!"<<endl; while(!feof(hSource); status = TRUE; /-/ 關(guān)閉文件if(hSource)if(fclose(hSource)cout<<"關(guān)閉原文件出錯(cuò)"<<endl;if(hDestination)if(fclose(hDestination)cout<<"關(guān)閉目標(biāo)文件出錯(cuò)"<<endl; /-/ 釋放內(nèi)存空間 if(pbBuffer

36、) free(pbBuffer); /-/ 銷毀會(huì)話密鑰if(hKey)if(!(CryptDestroyKey(hKey)cout<<"銷毀會(huì)話密鑰時(shí)出錯(cuò)"<<endl; /-/ 釋放CSP句柄if(hCryptProv)if(!(CryptReleaseContext(hCryptProv, 0)cout<<"釋放CSP句柄時(shí)出錯(cuò)!"<<endl; return status; / end DecryptfileHCRYPTPROV Dec:GetCryptProv()HCRYPTPROV hCrypt

37、Prov; / 加密服務(wù)提供者句柄/獲取加密提供者句柄if(CryptAcquireContext(&hCryptProv, / 加密服務(wù)提供者句柄NULL, / 密鑰容器名,這里使用登陸用戶名MS_ENHANCED_PROV, / 加密服務(wù)提供者 PROV_RSA_FULL, / 加密服務(wù)提供者類型,可以提供加密和簽名等功能0) / 標(biāo)志cout<<"加密服務(wù)提供者句柄獲取成功!n"/cout<<"加密服務(wù)提供者句柄獲取成功"<<endl;else/重新建立一個(gè)新的密鑰集 if(!CryptAcquireCo

38、ntext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) cout<<"重新建立一個(gè)新的密鑰集出錯(cuò)!"<<endl;return hCryptProv;HCRYPTKEY Dec:GenKeyFromFile(HCRYPTPROV hCryptProv,FILE* hSource)HCRYPTKEY hKey; PBYTE pbKeyBlob; DWORD dwKeyBlobLen; /從密文文件中獲取密鑰數(shù)據(jù)塊長度,并分配內(nèi)存空間. fread(&a

39、mp;dwKeyBlobLen, sizeof(DWORD), 1, hSource); if(ferror(hSource) | feof(hSource)cout<<"讀取密文文件中密鑰數(shù)據(jù)塊長度出錯(cuò)!"<<endl; if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen)cout<<"內(nèi)存分配出錯(cuò)"<<endl; /-/ 從密文文件中獲取密鑰數(shù)據(jù)塊fread(pbKeyBlob, 1, dwKeyBlobLen, hSource); if(ferror(hSourc

40、e) | feof(hSource)cout<<"讀取密文文件中密鑰數(shù)據(jù)塊出錯(cuò)!"<<endl; /-/ 導(dǎo)入會(huì)話密鑰到 CSP. if(!CryptImportKey( hCryptProv, pbKeyBlob, dwKeyBlobLen, 0, 0, &hKey) cout<<"Error during CryptImportKey!"<<endl; if(pbKeyBlob) free(pbKeyBlob);/返回導(dǎo)出的會(huì)話密鑰return hKey;HCRYPTKEY Dec:GenKey

41、ByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword)HCRYPTKEY hKey; HCRYPTHASH hHash;/-/ 創(chuàng)建哈希句柄. if(CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash)cout<<"一個(gè)哈希句柄已經(jīng)被創(chuàng)建. n"else cout<<"Error during CryptCreateHash!"<<endl; /-/ 計(jì)算輸入密碼的哈希值. if(CryptHashData( hH

42、ash, (BYTE *)szPassword, strlen(szPassword), 0) cout<<"此密碼已經(jīng)被添加到了哈希表中. n" else cout<<"Error during CryptHashData"<<endl; / 通過哈希值創(chuàng)建會(huì)話密鑰.if(CryptDeriveKey( hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey) cout<<"從這個(gè)密碼的哈希值獲得了一個(gè)加密密鑰. n" el

43、se cout<<"哈希值創(chuàng)建會(huì)話密鑰時(shí)出錯(cuò)!"<<endl; / 銷毀哈希句柄. if(hHash) if(!(CryptDestroyHash(hHash) cout<<"銷毀哈希句柄時(shí)出錯(cuò)"<<endl; hHash = 0;/返回創(chuàng)建的會(huì)話密鑰return hKey;主函數(shù)#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400#endif #include "Enc.h" /引入我們寫的加密頭文件#include "Dec.h&q

44、uot; /引入我們寫的解密頭文件#include <stdio.h>#include <string.h>#include <iostream>#include <conio.h> /需要的庫#include <windows.h> /需要的庫#include <wincrypt.h> /需要的庫using namespace std;#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) /* 這些宏定義有用,不可去除*/#define KE

45、YLENGTH 0x00800000HCRYPTPROV GetCryptProv(); /獲取加密提供者句柄的方法void main(void) Enc enc; /加密對(duì)象Dec dec; /解密對(duì)象 PCHAR szSource; /原文文件名 PCHAR szDestination; /加密后數(shù)據(jù)存儲(chǔ)文件CHAR szPassword100 = "" /用戶輸入口令,這里為ID碼 char response; /提示密碼信息選擇int choose; /處理方式選擇,是加密還是解密 1加密 2解密int endflag=1;char done;docout<&

46、lt;"請(qǐng)你選擇處理方式:"<<endl;cout<<"1.加密"<<endl;cout<<"2.解密"<<endl;cout<<endl;cin>>choose;switch(choose)case 1:/加密模塊if(!(szSource=(char *)malloc(100) /c語言的分配內(nèi)存方法cout<<"內(nèi)存分配失敗."<<endl;if(!(szDestination=(char *)mall

47、oc(100)cout<<"內(nèi)存分配失敗."<<endl;cout<<"加密一個(gè)文件. nn"cout<<"請(qǐng)輸入需要被加密文件的名稱(絕對(duì)路徑): "<<endl; /這里要很注意,輸入的需是絕對(duì)路徑,如:d:mytesta.txtcin>>szSource;cout<<"請(qǐng)輸入要輸出文件的名稱:"<<endl; /同樣絕對(duì)路徑,解密時(shí)也一樣cin>>szDestination;cout<<"要使用密碼對(duì)這個(gè)文件加密嗎(絕對(duì)路徑)? ( y/n )"<<endl;cin>>response;if(response = 'y')cout<<"請(qǐng)輸入密碼:"<<endl;cin&

溫馨提示

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

評(píng)論

0/150

提交評(píng)論