日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Crypto API 学习笔记一

發布時間:2024/6/5 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Crypto API 学习笔记一 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

標 題: 【原創】Crypto API 學習筆記一
作 者: jdxyw
時 間: 2006-09-01,16:47
鏈 接: http://bbs.pediy.com/showthread.php?t=31357
Crypto API 學習筆記一
微軟公司在NT4.0以上版本中提供了一套完整的Crypto API的函數,支持密鑰交換,數據加密解密,數字簽名,給程序員帶來了很大方便,用戶在對軟件進行保護的時候可以直接利用Crypto API來完成這些工作,比如計算注冊碼,檢查程序的完整性等。
? 我們在用這些的API進行加密解密的時候,只需要知道如何去應用它們,而不必知道它們的底層實現。如果想知道它們更為詳盡的資料,可以查找相關的資料。
? 對Crypto API只是業余型的感興趣,想通過寫學習筆記,一是讓自己記的更牢固些,二是想把自己的學的跟大家探討一下。寫的不好,大家多多原諒。我主要通過MSDN來學習,例子也是完全取自MSDN。
? 首先,是Crypto API運行的環境。
首先需要Crypt32.lib,將它加到project->setting->link下面,當然你也可以在程序中用#pragma comment (lib, "crypt32.lib")加入。
? 在程序開頭,你要加入兩個頭文件 windows.h 和 Wincrypt.h,和一個#define MY_ENCODING_TYPE? (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
? 在正式應用API進行一系列的加密解密的時候,需要有一些準備工作,下面是介紹一些在正式開始時所需要了解和做的工作。
生成密鑰和密鑰容器
? 我們知道,在進行加密解密的時候,我們需要一個密鑰進行加密,和一個密鑰進行解密,加密密鑰和解密密鑰可能相同,也可能不同。于是在我們進行加密解密的開始時,我們首先需要有密鑰。下面這個程序,完成了三個任務,并且介紹了一些函數的用法。
任務一:獲取一個指定的密鑰容器,如果這個容器不存在,創建一個。
任務二:如果容器中不存在一個簽名密鑰對,創建一個
任務三:如果容器中不存在一個交換密鑰對,創建一個
? //-------------------------------------------------------------------
下面這段程序使用到了這幾個函數

Code
CryptAcquireContext??
CryptDestroyKey??
CryptGenKey??
CryptGetUserKey??
//?Copyright?(c)?Microsoft?Corporation.??All?rights?reserved.?
#include?<stdio.h>?
#include?
<tchar.h>?
#include?
<windows.h>?
#include?
<Wincrypt.h>?
//-------------------------------------------------------------------?
void?MyHandleError(LPTSTR?psz)?
{?
????_ftprintf(stderr,?TEXT(
"An?error?occurred?in?the?program.?\n"));?
????_ftprintf(stderr,?TEXT(
"%s\n"),?psz);?
????_ftprintf(stderr,?TEXT(
"Error?number?%x.\n"),?GetLastError());?
????_ftprintf(stderr,?TEXT(
"Program?terminating.?\n"));?
????exit(
1);?
}?
//?End?of?MyHandleError.?

上面這個函數是一個異常處理函數,當出現錯誤的時候,出現提示,并推出程序。以后的程序中都有這個函數,以后就會將這個函數的實現省去。現在這個函數的實現在后面。

Code
void?main(void)??
{??
????????HCRYPTPROV?hCryptProv;???
//定義一個CSP模塊的句柄。“CSP模塊,請查看《加密解密二》222頁,那里有簡單的說明,這里就不說了。??????
????????LPCTSTR?pszContainerName?=?TEXT("My?Sample?Key?Container");//用一個TEXT宏定義一個容器的名字,?
????if(CryptAcquireContext(????????//這個函數是獲取有某個容器的CSP模塊的指針,成功返回TRUE。?
????????&hCryptProv,????????????//指向一個CSP模塊句柄指針,里面用指定的容器?
????????pszContainerName,???????//指定容器的名稱?
?????NULL,????????????????//這個參數這里用的是缺省值,指得是缺省得CSP模塊,你也可以傳入一個LPCTSTR類型的字符串,指定CSP模塊?
????????PROV_RSA_FULL,??????//確定密鑰的類型?
????????0))????????????????????//常設為0,還有些其他的類型,請看MSDN?
????{?
????????_tprintf(?
????????????TEXT(
"A?crypto?context?with?the?%s?key?container?")?
????????????TEXT(
"has?been?acquired.\n"),??
????????????pszContainerName);?
????}?
????
else?
????{??
????????
//不成功的處理段?
????????if(GetLastError()?==?NTE_BAD_KEYSET)?????//?NTE_BAD_KEYSET意味著密鑰?
//容器不存在,下面就去創建一個?
//新的密鑰容器?
????????{?
????????????
if(CryptAcquireContext(?
????????????????
&hCryptProv,??
????????????????pszContainerName,??
????????????????NULL,??
????????????????PROV_RSA_FULL,??
????????????????CRYPT_NEWKEYSET))???????????
//?CRYPT_NEWKEYSET意味著當指定容器不存在的時候,去創建一個容器。?
????????????{?
????????????????_tprintf(TEXT(
"A?new?key?container?has?been?")?
????????????????????TEXT(
"created.\n"));?
????????????}?
????????????
else?
????????????{?
????????????????MyHandleError(TEXT(
"Could?not?create?a?new?key?")?
????????????????????TEXT(
"container.\n"));?
????????????}?
????????}?
????????
else?
????????{?
????????????MyHandleError(TEXT(
"CryptAcquireContext?failed.\n"));?
????????}?
????}?
????HCRYPTKEY?hKey;????????????????????????????
//創建一個密鑰句柄?
????if(CryptGetUserKey(???????????????????????????//?CryptGetUserKey是獲取一個密鑰//句柄的函數,成功返回TRUE?
????????hCryptProv,???????????????????????????????//指定容器的CSP模塊句柄?
????????AT_SIGNATURE,?????????????????????????//指定私鑰的類型?
????????&hKey))????????????????????????????????//原來接收獲取的密鑰句柄?
????{?
????????_tprintf(TEXT(
"A?signature?key?is?available.\n"));?
????}?
????
else?
????{?
????????_tprintf(TEXT(
"No?signature?key?is?available.\n"));?
????????
if(GetLastError()?==?NTE_NO_KEY)??????????????//?NTE_NO_KEY意味著密鑰不存在,下面就生成一個密鑰?
????????{?
????????????_tprintf(TEXT(
"The?signature?key?does?not?exist.\n"));?
????????????_tprintf(TEXT(
"Create?a?signature?key?pair.\n"));??
????????????
if(CryptGenKey(??????????????????????????//?CryptGenKey生成一個密鑰?
????????????????hCryptProv,??????????????????????????//指定CSP模塊的句柄?
????????????????AT_SIGNATURE,????????????????????//對于公鑰密碼系統,生成一個私鑰和一個公鑰,這個參數指定了這個密鑰是公鑰,于是生成了一個密碼對。如果不是公鑰系統,則指定了密碼算法,具體看MSDN。?
????????????????0,?????????????????????????????????//指定了生成密鑰的類型,這個參數的說明挺多的,想獲取更為詳盡的資料請看MSDN。?
????????????????&hKey))??
????????????{?
????????????????_tprintf(TEXT(
"Created?a?signature?key?pair.\n"));?
????????????}?
????????????
else?
????????????{?
????????????????MyHandleError(TEXT(
"Error?occurred?creating?a?")?
????????????????????TEXT(
"signature?key.\n"));??
????????????}?
????????}?
????????
else?
????????{?
????????????MyHandleError(TEXT(
"An?error?other?than?NTE_NO_KEY?")?
????????????????TEXT(
"getting?a?signature?key.\n"));?
????????}?
????}?
//?End?if.?
????_tprintf(TEXT("A?signature?key?pair?existed,?or?one?was?")?
????????TEXT(
"created.\n\n"));?
????????
if(hKey)??????????????????????????????//將密鑰句柄銷毀?
????{?
????????
if(!(CryptDestroyKey(hKey)))?
????????{?
????????????MyHandleError(TEXT(
"Error?during?CryptDestroyKey."));?
????????}?
????????hKey?
=?NULL;?
????}??
????下面這部分和上面是類似的,只不過密鑰類型不相同而已。?
????
if(CryptGetUserKey(?
????????hCryptProv,?
????????AT_KEYEXCHANGE,?
????????
&hKey))??
????{?
????????_tprintf(TEXT(
"An?exchange?key?exists.\n"));?
????}?
????
else?
????{?
????????_tprintf(TEXT(
"No?exchange?key?is?available.\n"));?
????????
//?Check?to?determine?whether?an?exchange?key??
????????
//?needs?to?be?created.?
????????if(GetLastError()?==?NTE_NO_KEY)??
????????{??
????????????
//?Create?a?key?exchange?key?pair.?
????????????_tprintf(TEXT("The?exchange?key?does?not?exist.\n"));?
????????????_tprintf(TEXT(
"Attempting?to?create?an?exchange?key?")?
????????????????TEXT(
"pair.\n"));?
????????????
if(CryptGenKey(?
????????????????hCryptProv,?
????????????????AT_KEYEXCHANGE,?
????????????????
0,?
????????????????
&hKey))??
????????????{?
????????????????_tprintf(TEXT(
"Exchange?key?pair?created.\n"));?
????????????}?
????????????
else?
????????????{?
????????????????MyHandleError(TEXT(
"Error?occurred?attempting?to?")?
????????????????????TEXT(
"create?an?exchange?key.\n"));?
????????????}?
????????}?
????????
else?
????????{?
????????????MyHandleError(TEXT(
"An?error?other?than?NTE_NO_KEY?")?
????????????????TEXT(
"occurred.\n"));?
????????}?
????}?
????
//?Destroy?the?exchange?key.?
????if(hKey)?
????{?
????????
if(!(CryptDestroyKey(hKey)))?
????????{?
????????????MyHandleError(TEXT(
"Error?during?CryptDestroyKey."));?
????????}?
????????hKey?
=?NULL;?
????}?
????
//?Release?the?CSP.?
????if(hCryptProv)?
????{?
????????
if(!(CryptReleaseContext(hCryptProv,?0)))?
????????{?
????????????MyHandleError(TEXT(
"Error?during?CryptReleaseContext."));?
????????}?
????}??
????_tprintf(TEXT(
"Everything?is?okay.?A?signature?key?"));?
????_tprintf(TEXT(
"pair?and?an?exchange?key?exist?in?"));?
????_tprintf(TEXT(
"the?%s?key?container.\n"),?pszContainerName);???
}?
//?End?main.

?

? 下面我們再通過一個程序,用幾種不同的方法,將CryptAcquireContext和其他的API函數聯系起來,看看它們是如何與一個CSP和容器工作的。這個程序演示了以下內容和幾個函數。
一.? 用CryptAcquireContext獲取一個缺省容器的缺省CSP的句柄。如果缺省容器不存在,用CryptAcquireContext創建一個。
二.? 用CryptGetProvParam獲取CSP和容器的信息。
三.? 用CryptContextAddRef增加CSP的引用計數器的數值。
四.? 用CryptAcquireContext創建一個指定的容器
五.? 用CryptAcquireContext刪除一個容器
六.? 用一個新創建的容器獲取一個CSP的句柄。

Code
#include?<stdio.h>?
#include?
<tchar.h>?
#include?
<windows.h>?
#include?
<Wincrypt.h>?
異常處理函數省略?
void?main(void)?
{?
????HCRYPTPROV?hCryptProv;????????????????????????????
//定義CSP句柄?
????if(CryptAcquireContext(?
????????
&hCryptProv,??
????????NULL,???????????????????????????????????????????
//缺省容器?
????????NULL,???????????????????????????????????????????//缺省CSP?
????????PROV_RSA_FULL,??
????????
0))??
????{?
????????_tprintf(TEXT(
"CryptAcquireContext?succeeded.\n"));?
????}?
????
else?
????{?
????????
if?(GetLastError()?==?NTE_BAD_KEYSET)???????????????//同樣,如果當不存在這樣的容器的時候,創建一個?
????????{?
????????????
if(CryptAcquireContext(?
????????????????
&hCryptProv,??
????????????????NULL,??
????????????????NULL,??
????????????????PROV_RSA_FULL,??
????????????????CRYPT_NEWKEYSET))??????????????????????
????????????{?
????????????????_tprintf(TEXT(
"CryptAcquireContext?succeeded.\n"));?
????????????}?
????????????
else?
????????????{?
????????????????MyHandleError(TEXT(
"Could?not?create?the?default?")?
????????????????????TEXT(
"key?container.\n"));?
????????????}?
????????}?
????????
else?
????????{?
????????????MyHandleError(TEXT(
"A?general?error?running?")?
????????????????TEXT(
"CryptAcquireContext."));?
????????}?
????}?
????CHAR?pszName[
1000];?
????DWORD?cbName;?
????cbName?
=?1000;?
????
if(CryptGetProvParam(?
????????hCryptProv,?????????????????????????????????????
//CSP模塊句柄?
????????PP_NAME,?????????????????????????????????????//指定獲取哪些信息,這里是指定獲取CSP名字的信息?
????????(BYTE*)pszName,???????????????????????????????//緩沖區接受信息返回值?
????????&cbName,??
????????
0))?
????{?
????????_tprintf(TEXT(
"CryptGetProvParam?succeeded.\n"));?
????????printf(
"Provider?name:?%s\n",?pszName);?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?reading?CSP?name.\n"));?
????}?
????
//---------------------------------------------------------------?
????
//?Read?the?name?of?the?key?container.?
????cbName?=?1000;?
????
if(CryptGetProvParam(?
????????hCryptProv,??
????????PP_CONTAINER,???????????????????????????????????????
//獲取容器名字?
????????(BYTE*)pszName,??
????????
&cbName,??
????????
0))?
????{?
????????_tprintf(TEXT(
"CryptGetProvParam?succeeded.\n"));?
????????printf(
"Key?Container?name:?%s\n",?pszName);?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?reading?key?container?name.\n"));?
????}?
????
if(CryptContextAddRef(???????????????????????//?CryptContextAddRef是向一個CSP的引用計數器增加一個值的函數?
????????hCryptProv,??
????????NULL,????????????????????????????????
//保留值,必須為NULL?
????????0))?????????????????????//保留值,必須為0?
????{?
????????_tprintf(TEXT(
"CryptcontextAddRef?succeeded.\n"));?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?during?CryptContextAddRef!\n"));?
????}?
????
//---------------------------------------------------------------?
????
//??The?reference?count?on?hCryptProv?is?now?greater?than?one.??
????
//??The?first?call?to?CryptReleaseContext?will?not?release?the??
????
//??provider?handle.??
????
//---------------------------------------------------------------?
????
//??Release?the?context?once.?
????if?(CryptReleaseContext(hCryptProv,?0))????????????????//?CryptReleaseContext是用來釋放CSP句柄的,當這個函數調用一次的時候,CSP里面的引用計數就減少一,當引用計數減少的0的時候。CSP將不能再被這個程序中的任何函數調用了。?
????{?
????????_tprintf(TEXT(
"The?first?call?to?CryptReleaseContext?")?
????????????TEXT(
"succeeded.\n"));?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?during?")?
????????????TEXT(
"CryptReleaseContext?#1!\n"));?
????}?
????
if?(CryptReleaseContext(hCryptProv,?0))????????????????//再次釋放CSP模塊?
????{?
????????_tprintf(TEXT(
"The?second?call?to?CryptReleaseContext?")?
????????????TEXT(
"succeeded.\n"));?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?during?")?
????????????TEXT(
"CryptReleaseContext?#2!\n"));?
????}?
???下面是從PROV_RSA_FULL的CSP模塊中創建一個自己的容器?
????LPCTSTR?pszContainerName?
=?TEXT("My?Sample?Key?Container");?
????hCryptProv?
=?NULL;?
????
if(CryptAcquireContext(?
????????
&hCryptProv,??
????????pszContainerName,?
????????NULL,??
????????PROV_RSA_FULL,??
????????CRYPT_NEWKEYSET))??
????{?
????????_tprintf(TEXT(
"CryptAcquireContext?succeeded.?\n"));?
????????_tprintf(TEXT(
"New?key?set?created.?\n"));??
????????
//-----------------------------------------------------------?
????????
//?Release?the?provider?handle?and?the?key?container.?
????????if(hCryptProv)?
????????{?
????????????
if(CryptReleaseContext(hCryptProv,?0))??
????????????{?
????????????????hCryptProv?
=?NULL;?
????????????????_tprintf(TEXT(
"CryptReleaseContext?succeeded.?\n"));?
????????????}?
????????????
else?
????????????{?
????????????????MyHandleError(TEXT(
"Error?during?")?
????????????????????TEXT(
"CryptReleaseContext!\n"));?
????????????}?
????????}?
????}?
????
else?
????{?
????????
if(GetLastError()?==?NTE_EXISTS)?
????????{?
????????????_tprintf(TEXT(
"The?named?key?container?could?not?be?")?
????????????????TEXT(
"created?because?it?already?exists.\n"));?
????????}?
????????
else?
????????{?
????????????MyHandleError(TEXT(
"Error?during?CryptAcquireContext?")?
????????????????TEXT(
"for?a?new?key?container."));?
????????}?
????}?
????
if(CryptAcquireContext(?
????????
&hCryptProv,??
????????pszContainerName,??
????????NULL,??
????????PROV_RSA_FULL,?
????????
0))??
????{?
????????_tprintf(TEXT(
"Acquired?the?key?set?just?created.?\n"));?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?during?CryptAcquireContext!\n"));?
????}?
????
//---------------------------------------------------------------?
????
//?Perform?cryptographic?operations.?
????
//---------------------------------------------------------------?
???????if(CryptReleaseContext(?
????????hCryptProv,??
????????
0))??
????{?
????????_tprintf(TEXT(
"CryptReleaseContext?succeeded.?\n"));?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?during?CryptReleaseContext!\n"));?
????}?
????
if(CryptAcquireContext(?
????????
&hCryptProv,??
????????pszContainerName,??
????????NULL,??
????????PROV_RSA_FULL,?
????????CRYPT_DELETEKEYSET))????????????????????
//CRYPT_DELETEKEYSET意味著CryptAcquireContex刪除一個指定的容器?
????{?
????????_tprintf(TEXT(
"Deleted?the?key?container?just?created.?\n"));?
????}?
????
else?
????{?
????????MyHandleError(TEXT(
"Error?during?CryptAcquireContext!\n"));?
????}?
}?

?

轉載于:https://www.cnblogs.com/wanghao111/archive/2009/05/25/1489031.html

總結

以上是生活随笔為你收集整理的Crypto API 学习笔记一的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。