本节说明了目标用户端实现三相密钥交换协议所需的代码。发送用户和目的用户之间的通信的细节未显示,因为这些对于每个实现将是不同的。
#include < wincrypt.h >
HCRYPTPROV hProv = 0;
#define BLOB_SIZE 256
BYTE pbDestName[NAME_SIZE];
DWORD dwDestNameLen;
BYTE pbSendName[NAME_SIZE];
DWORD dwSendNameLen;
HCRYPTKEY hSendPubKey = 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 pbSendHash[HASH_SIZE];
DWORD dwSendHashLen;
HCRYPTHASH hHash = 0;
//获取默认提供程序的句柄。
CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0);
//获取发送用户的交换公钥。将其导入
// CSP并在'hSendPubKey'中放置一个句柄。
...
//获取发送用户的名字。这通常是在
//同时获得公钥。放在这里
//'pbSendName',并将'dwSendNameLen'设置为字节数
// 名字。
...
//将目标用户的名称放在'pbDestName'并设置
//'dwDestNameLen'到名称中的字节数。
...
//从发送用户接收包含会话密钥A的密钥blob
//并将其放在'pbKeyBlob'中。将'dwBlobLen'设置为数
//字节在键blob。
...
//将关键点blob导入CSP。
CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hKeyA);
//创建一个随机会话密钥(会话密钥B)。因为这个关键是
//将仅用于密钥交换而不是加密
//这里没有指定哪种算法。
CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKeyB);
//将会话密钥B导出为简单的密钥blob。
dwBlobLen = BLOB_SIZE;
CryptExportKey(hKeyB,hSendPubKey,SIMPLEBLOB,0,pbKeyBlob,{989 796 005} dwBlobLen);
//发送包含会话密钥B的密钥b给发送用户。
...
//
//计算哈希值并将其发送给发送用户。
//
//创建哈希对象。
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 2", 7, 0);
//完成哈希计算并检索哈希值。
dwHashLen = HASH_SIZE;
CryptGetHashParam(hHash,HP_HASHVALUE,pbHash,& dwHashLen,0);
//销毁哈希对象。
CryptDestroyHash(hHash);
//将哈希值发送给发送用户。
...
//等待发送用户响应。
...
//从发送用户接收哈希值并将其放入
//“Pbsendsvlua。将'dwSendHashLen'设置为字节数
//哈希值。
...
//
//验证从发送用户收到的哈希值。
//
//创建哈希对象。
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));
//
//比较从发送用户接收的哈希值
//我们刚刚计算出的哈希值。如果不匹配的话
//终止协议。
//
if(dwHashLen!=dwSendHashLen || memcmp(pbHash, pbSendHash, dwHashLen)) {
printf("Key exchange protocol failed in phase 3!\n");
printf("Aborting protocol!\n");
return;
}
//
//使用会话密钥B加密发送给发件人的邮件。
//使用会话密钥A来解密从发件人接收的邮件。
//
...
//销毁会话密钥。
CryptDestroyKey(hKeyA);
CryptDestroyKey(hKeyB);
//销毁发送用户公钥的句柄。
CryptDestroyKey(hSharedKey);
//发布提供者句柄。
CryptReleaseContext(hProv, 0);