发件人代码示例

【勇芳软件工作室】汉化HomePreviousNext

本节显示发送用户端实现三相密钥交换协议所需的代码。发送用户和目的用户之间的通信的细节没有显示,因为这些对于每个实现将是不同的。

为了可读性,这个例子和以下一个公然地避免了两个主要方面的良好的编程实践:

*不显示错误检查。工作程序应始终检查返回的错误代码,并在遇到错误时执行一些适当的操作。

*固定长度的缓冲区用于存储密钥和散列值。实际上,这些缓冲区应该动态分配,因为这个数据会根据所使用的CSP而有所不同。

#include < wincrypt.h >

HCRYPTPROV hProv = 0;

#define BLOB_SIZE 256

BYTE pbDestName[NAME_SIZE];

DWORD dwDestNameLen;

BYTE pbSendName[NAME_SIZE];

DWORD dwSendNameLen;

HCRYPTKEY hDestPubKey = 0;

HCRYPTKEY hKeyA = 0;

HCRYPTKEY hKeyB = 0;

#define HASH_SIZE 256

BYTE pbKeyBlob[BLOB_SIZE];

DWORD dwBlobLen;

// Obtain the sending user's exchange public key.

BYTE pbHash[HASH_SIZE];

DWORD dwHashLen;

BYTE pbDestHash[HASH_SIZE];

DWORD dwDestHashLen;

HCRYPTHASH hHash = 0;

//获取默认提供程序的句柄。

CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0);

//获取目标用户的交换机公钥。将其导入

// CSP并在'hDestPubKey'中放置一个句柄。

...

CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hDestPubKey);

//获取目标用户的名字。这通常是在

//同时获得公钥。放在这里

//'pbDestName'并将'dwDestNameLen'设置为字节数

// 名字。

...

//将发送用户的名称放在'pbSendName'并设置

//'dwSendNameLen'到其中的字节数。

...

//创建一个随机会话密钥(会话密钥A)。因为这个钥匙会

//仅用于密钥交换而不是加密

//这里没有指定哪种算法。

CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKeyA);

//将会话密钥A导出为一个简单的密钥blob。

dwBlobLen = BLOB_SIZE;

CryptExportKey(hKeyA,hDestPubKey,SIMPLEBLOB,0,pbKeyBlob,& dwBlobLen);

//发送包含会话密钥A的密钥blob到目标用户。

...

//等待目标用户响应。

...

//从目的地接收包含会话密钥B的密钥blob

//用户并将其放在'pbKeyBlob'中。将'dwBlobLen'设置为数字

//关键blob中的字节。

...

//从目标用户接收哈希值并将其放入

//“Pbsvlua。将'dwHashLen'设置为散列中的字节数

//值。

...

//将关键点blob导入CSP。

CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hKeyB);

//

//验证从目标用户接收的哈希值。

//

//创建哈希对象。

CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);

//将会话密钥A添加到哈希。

CryptHashSessionKey(hHash, hKeyA, 0);

//将目标用户名添加到哈希。

CryptHashData(hHash, pbDestName, dwDestNameLen, 0);

//将会话密钥B添加到哈希。

CryptHashSessionKey(hHash, hKeyB, 0);

//将发送用户名添加到哈希。

CryptHashData(hHash, pbSendName, dwSendNameLen, 0);

//将“阶段2”文本添加到哈希。

CryptHashData(hHash, "phase 3", 7, 0);

//完成哈希计算并检索哈希值。

dwHashLen = HASH_SIZE;

CryptGetHashParam(hHash,HP_HASHVALUE,pbHash,& dwHashLen,0);

//销毁哈希对象。

CryptDestroyHash(hHash);

//

//比较从目标用户接收的哈希值

//我们刚刚计算出的哈希值。如果不匹配的话

//终止协议。

//

if(dwHashLen!=dwDestHashLen || memcmp(pbHash, pbDestHash, dwHashLen)) {

printf("Key exchange protocol failed in phase 2!\n");

printf("Aborting protocol!\n");

return;

}

//

//计算要发送给目标用户的哈希值。

//

//创建哈希对象。

CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);

//将会话密钥B添加到哈希。

CryptHashSessionKey(hHash, hKeyB, 0);

//将发送用户名添加到哈希。

CryptHashData(hHash, pbSendName, dwSendNameLen, 0);

//将目标用户名添加到哈希。

CryptHashData(hHash, pbDestName, dwDestNameLen, 0);

//添加“阶段3”文本到哈希。

CryptHashData(hHash, "phase 3", 7, 0);

//完成哈希计算并检索哈希值。

dwHashLen = HASH_SIZE;

CryptGetHashParam(hHash,HP_HASHVALUE,pbHash,& dwHashLen,0);

//销毁哈希对象。

CryptDestroyHash(hHash);

//将哈希值发送到目标用户。

...

//

//使用会话密钥A加密发送到接收者的邮件。

//使用会话密钥B来解密从接收者接收的消息。

//

...

//销毁会话密钥。

CryptDestroyKey(hKeyA);

CryptDestroyKey(hKeyB);

//发布提供者句柄。

CryptReleaseContext(hProv, 0);