Sender Code Example
This section shows the code needed on the sending user side to implement the
three-phase key exchange protocol. The details of the communication between the
sending user and the destination user are not shown, because these will be
different for each implementation.
For purposes of readability, this example and the following one blatantly
avoid good programming practice in two major ways:
- No error checking is shown. A working program should always check the returned
error codes and perform some appropriate action when an error is encountered.
- Fixed-length buffers are used to store key blobs and hash values. In practice,
these buffers should be allocated dynamically, because this data will vary in
size depending on the CSP used.
#include <wincrypt.h>
HCRYPTPROV hProv = 0;
#define NAME_SIZE 256
BYTE pbDestName[NAME_SIZE];
DWORD dwDestNameLen;
BYTE pbSendName[NAME_SIZE];
DWORD dwSendNameLen;
HCRYPTKEY hDestPubKey = 0;
HCRYPTKEY hKeyA = 0;
HCRYPTKEY hKeyB = 0;
#define BLOB_SIZE 256
BYTE pbKeyBlob[BLOB_SIZE];
DWORD dwBlobLen;
#define HASH_SIZE 256
BYTE pbHash[HASH_SIZE];
DWORD dwHashLen;
BYTE pbDestHash[HASH_SIZE];
DWORD dwDestHashLen;
HCRYPTHASH hHash = 0;
// Get handle to the default provider.
CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0);
// Obtain the destination user's exchange public key. Import it into
// the CSP and place a handle to it in 'hDestPubKey'.
...
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hDestPubKey);
// Obtain the destination user's name. This is usually done at the
// same time as the public key was obtained. Place this in
// 'pbDestName' and set 'dwDestNameLen' to the number of bytes in
// the name.
...
// Place the sending user's name in 'pbSendName' and set
// 'dwSendNameLen' to the number of bytes in it.
...
// Create a random session key (session key A). Because this key will
// be used solely for key exchange and not encryption, it
// does not matter which algorithm you specify here.
CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKeyA);
// Export session key A into a simple key blob.
dwBlobLen = BLOB_SIZE;
CryptExportKey(hKeyA, hDestPubKey, SIMPLEBLOB, 0, pbKeyBlob, &dwBlobLen);
// Send key blob containing session key A to the destination user.
...
// Wait for the destination user to respond.
...
// Receive a key blob containing session key B from the destination
// user and place it in 'pbKeyBlob'. Set 'dwBlobLen' to the number
// of bytes in the key blob.
...
// Receive a hash value from the destination user and place it in
// 'pbHashValue'. Set 'dwHashLen' to the number of bytes in the hash
// value.
...
// Import the key blob into the CSP.
CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hKeyB);
//
// Verify hash value received from the destination user.
//
// Create hash object.
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
// Add session key A to hash.
CryptHashSessionKey(hHash, hKeyA, 0);
// Add destination user's name to hash.
CryptHashData(hHash, pbDestName, dwDestNameLen, 0);
// Add session key B to hash.
CryptHashSessionKey(hHash, hKeyB, 0);
// Add sending user's name to hash.
CryptHashData(hHash, pbSendName, dwSendNameLen, 0);
// Add "phase 2" text to hash.
CryptHashData(hHash, "phase 3", 7, 0);
// Complete the hash computation and retrieve the hash value.
dwHashLen = HASH_SIZE;
CryptGetHashParam(hHash, HP_HASHVALUE, pbHash, &dwHashLen, 0);
// Destroy the hash object.
CryptDestroyHash(hHash);
//
// Compare the hash value received from the destination user with
// the hash value that we just computed. If they do not match, then
// terminate the protocol.
//
if(dwHashLen!=dwDestHashLen || memcmp(pbHash, pbDestHash, dwHashLen)) {
printf("Key exchange protocol failed in phase 2!\n");
printf("Aborting protocol!\n");
return;
}
//
// Compute hash to be sent to the destination user.
//
// Create hash object.
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
// Add session key B to hash.
CryptHashSessionKey(hHash, hKeyB, 0);
// Add sending user's name to hash.
CryptHashData(hHash, pbSendName, dwSendNameLen, 0);
// Add destination user's name to hash.
CryptHashData(hHash, pbDestName, dwDestNameLen, 0);
// Add "phase 3" text to hash.
CryptHashData(hHash, "phase 3", 7, 0);
// Complete the hash computation and retrieve the hash value.
dwHashLen = HASH_SIZE;
CryptGetHashParam(hHash, HP_HASHVALUE, pbHash, &dwHashLen, 0);
// Destroy the hash object.
CryptDestroyHash(hHash);
// Send the hash value to the destination user.
...
//
// Use session key A to encrypt messages sent to the receiver.
// Use session key B to decrypt messages received from the receiver.
//
...
// Destroy session keys.
CryptDestroyKey(hKeyA);
CryptDestroyKey(hKeyB);
// Release provider handle.
CryptReleaseContext(hProv, 0);
- Software for developers
-
Delphi Components
.Net Components
Software for Android Developers
- More information resources
-
MegaDetailed.Net
Unix Manual Pages
Delphi Examples
- Databases for Amazon shops developers
-
Amazon Categories Database
Browse Nodes Database