|
| БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО! |
|
|
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 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);
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
Кодовый Пример Передатчика
Эта секция показывает код, которому нужно на посылающей стороне потребителя, чтобы осуществлять трех фаза ключевой биржевой протокол. Детали связи между посылающим потребителем и потребитель расположения не показаны, поскольку эти будут другими для каждой реализации.
Для целей удобочитаемости, этот пример и следующее один крикливо избегать хорошего программирования практики в двух основных путях:
Проверка No ошибки показана. Работа программы должна всегда проверять возвращанную ошибку кодировать и выполнять некоторое подходящее действие когда ошибка столкнулась. Фиксированная длина буферов использованы, чтобы загружать ключевые капли и обсуждать величины. На практике, эти буферы должны распределяться динамически, поскольку эти данные изменится по величине в зависимости от CSP использованное.
#include HCRYPTPROV hProv = 0;
#define NAME_SIZE 256 BYTE pbDestName[NAME_SIZE]; DWORD dwDestNameLen; БАЙТ 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; БАЙТ pbDestHash[HASH_SIZE]; DWORD dwDestHashLen; HCRYPTHASH hHash = 0;
// Получите ручку по умолчанию поставщику.
CryptAcquireContext(&hProv, НЕДЕЙСТВИТЕЛЬНЫЙ, НЕДЕЙСТВИТЕЛЬНЫЙ, PROV_RSA_FULL, 0);
// Получите пользователя расположения биржевой общественной клавиши. Импортируйте это в // CSP и устанавливайте ручку, чтобы это в 'hDestPubKey. ... CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hDestPubKey);
// Получите имя пользователя расположения. Это обычно сделан в // том же времени хотя общественная клавиша была получена. Установите это в // 'pbDestName и установленное 'dwDestNameLen в количество байтов в // имя. ...
// Место имя пользователя посылки в 'pbSendName и установленное
// 'dwSendNameLen В количество байтов в этом. ...
// Создайте произвольную сеансовую клавишу (сеансовую клавишу A). Поскольку эта клавиша будет // использоваться исключительно для ключевого обмена и не шифрования, это // не имеет значения какой алгоритм, который Вы определяете здесь. CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKeyA);
// Экспортная сеансовая клавиша into простая ключевая капля. dwBlobLen = BLOB_SIZE; CryptExportKey(hKeyA, hDestPubKey, SIMPLEBLOB, 0, pbKeyBlob, &dwBlobLen);
// Пошлите ключевой содержащей сеансовой клавише капли to пользователь расположения.
...
// Ожидание пользователь расположения, чтобы отвечать. ...
// Получите ключевую содержащую сеансовую клавишу капли B из расположения // пользователь и устанавливайте это в 'pbKeyBlob. Установите 'dwBlobLen в число // байтов в ключевой капле. ...
// Приемник величина хэша из пользователя расположения и место это в // 'pbHashValue. Установите 'dwHashLen в количество байтов в хэше // величина. ...
// Импортируйте ключевую каплю в CSP. CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hKeyB);
// // Проверьте величину хэша полученную из пользователя расположения. //
// Создайте объект хэша. CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
// Добавьте сеансовой клавише to хэш. CryptHashSessionKey(hHash, hKeyA, 0);
// Добавьте имя пользователя расположения, чтобы обсуждаться. CryptHashData(hHash, pbDestName, dwDestNameLen, 0);
// Добавьте сеансовую клавишу B, чтобы обсуждаться. CryptHashSessionKey(hHash, hKeyB, 0);
// Добавьте имя пользователя посылки обсуждаться. CryptHashData(hHash, pbSendName, dwSendNameLen, 0);
// Добавьте текст "фазы 2", чтобы обсуждаться. CryptHashData(hHash, "ФАЗА 3", 7, 0);
// Завершите вычисление хэша и извлекайте величину хэша. dwHashLen = HASH_SIZE; CryptGetHashParam(hHash, HP_HASHVALUE, pbHash, &dwHashLen, 0);
// Уничтожьте объект хэша. CryptDestroyHash(hHash);
// // Сравнение величина хэша получала из пользователя расположения с // величину хэша, что мы только что вычислили. Если они не сочетаются, тогда // завершать протокол. //
если(dwHashLen!=dwDestHashLen || memcmp(pbHash, pbDestHash, dwHashLen)) {
printf(биржевой протокол "Key терпел неудачу в фазе 2!\n"); printf(протокол "Aborting!\n"); возврат; }
// // Вычислите хэш, чтобы быть посланн пользователю расположения. //
// Создайте объект хэша. 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, "ФАЗА 3", 7, 0);
// Завершите вычисление хэша и извлекайте величину хэша. dwHashLen = HASH_SIZE; CryptGetHashParam(hHash, HP_HASHVALUE, pbHash, &dwHashLen, 0);
// Уничтожьте объект хэша. CryptDestroyHash(hHash);
// Пошлите хэшу величину пользователю расположения. ...
// // Сеансовая клавиша Использования to кодировать сообщения посланные получателю. // Сеансовая клавиша Использования B, чтобы декодировать сообщения полученные из получателя.
// ...
// Уничтожьте сеансовые клавиши. CryptDestroyKey(hKeyA); CryptDestroyKey(hKeyB);
// Ручка поставщика Версии. CryptReleaseContext(hProv, 0);
|
|
|
|
| |