
Бывалый

Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008
Репутация: нет Всего: 3
|
Доброго времени суток! Пишу ПО, испольующее свой сетевой протокол (а как иначе?), шифрующийся при передаче информации. Встала проблема работы с алгоритмами шифрования. В результате выбор пал на Blowfish. Так как ПО кроссплатформенное, то в качестве библиотеки шифрования была выбрана OpenSSL, включающая в себя (помимо прочего) Blowfish. После пары недель мучений и поисков док (которых особо нет) таки получилось что-то рабочее. С чем и хочу поделиться, вдруг кто-то сталкнется с подобной задачей. Представленный далее код выполнен в виде законченного тестового приложения, демонстрирующего шифрование строки и последовательности из символов в шестнадцатиричной системе счисления (хексами). Дешифрование происходит только по первому шифру ибо нет смысла из одной и той же зашифрованной последовательности производить дешифрование. Код с комментариями ниже. Код | #include <iostream> #include <cstring> #include <stdlib.h> #include <openssl/evp.h>
//////////////////
#define BUFFER_SIZE 1024 #define CRYPT_SIZE 42
//////////////////
using namespace std;
//////////////////
// Passphrase key unsigned char key[16] = { 0x6b,0x60,0xcb,0x5b, 0x82,0xce,0x90,0xb1, 0xcc,0x2b,0x6c,0x55, 0x6a,0x6b,0x6c,0x6d }; // Init vector (not use and not needed, coz 0x00) unsigned char iv[] = {0x00};
//////////////////
/* * Encrypt function * Parameters: * - data - string to encrypt * - result - result encrypted string */ int do_bf_encrypt(unsigned char *data, unsigned char *result, unsigned char *key) { int result_len = 0; EVP_CIPHER_CTX ctx;
// init context EVP_CIPHER_CTX_init(&ctx);
// init encryption mechanism if (-1 == EVP_EncryptInit(&ctx, EVP_bf_cbc(), key, iv)) { return -1; }
// encrypt data if (-1 == EVP_EncryptUpdate(&ctx, result, &result_len, data, strlen((const char *)data))) { return -1; }
// finalize encryption if (-1 == EVP_EncryptFinal(&ctx, result+result_len, &result_len)) { return -1; }
// clear context EVP_CIPHER_CTX_cleanup(&ctx);
return 0; }
//////////////////
/* * Decrypt function * Parameters: * - data - string to decrypt * - result - result decrypted string * - key */ int do_bf_decrypt(unsigned char *data, unsigned char *result, unsigned char *key) { int result_len = 0; EVP_CIPHER_CTX ctx;
// init context EVP_CIPHER_CTX_init(&ctx);
// init decrypt mechanism if (-1 == (EVP_DecryptInit(&ctx, EVP_bf_cbc(), key, iv))) { return -1; }
// decrypt data if (-1 == EVP_DecryptUpdate(&ctx, result, &result_len, data, strlen((const char*)data))) { return -1; }
// finalize decryption if (-1 == EVP_DecryptFinal(&ctx, result+result_len, &result_len)) { return -1; }
// clear context EVP_CIPHER_CTX_cleanup(&ctx);
return 0; }
//////////////////
int main(int argc, char **argv) { unsigned char data_hex[] = { 0x31, 0x32, 0x33, // 123 0x61, 0x62, 0x63, // abc 0x41, 0x42, 0x43, // ABC 0x00 }; unsigned char result[CRYPT_SIZE]; unsigned char decrypt_result[BUFFER_SIZE]; unsigned char data[BUFFER_SIZE] = "123abcABC";
memset(result, 0x00, CRYPT_SIZE);
cout << "String (data): " << data << endl; cout << "String (data_hex): " << data_hex << endl;
// try encrypt try { do_bf_encrypt(data, result, key); cout << "Encrypt result (data): " << result << endl; do_bf_encrypt(data_hex, result, key); cout << "Encrypt result (data_hex): " << result << endl; } catch (int e) { cerr << "Some error here" << endl; return EXIT_FAILURE; }
// try decrypt try { memset(decrypt_result, 0x00, BUFFER_SIZE); do_bf_decrypt(result, decrypt_result, key); cout << "Decrypt result (data): " << decrypt_result << endl; } catch (int e) { cerr << "Some error here" << endl; return EXIT_FAILURE; } cout << "String (data, after encrypt): " << data << endl; cout << "String (data_hex, after encrypt): " << data_hex << endl;
return EXIT_SUCCESS; }
|
Вывод: Код | String (data): 123abcABC String (data_hex): 123abcABC Encrypt result (data): ▒*aa▒Ԏ▒▒▒'|?▒ Encrypt result (data_hex): ▒*aa▒Ԏ▒▒▒'|?▒ Decrypt result (data): 123abcABC String (data, after encrypt): 123abcABC String (data_hex, after encrypt): 123abcABC
|
Хотелось бы уточнить, все ли тут правильно сделано? Не забываем, что этот пример только для коротких строк. Для длинных строк или файлов нужно использовать в цикле EVP_EncryptUpdate / EVP_DecryptUpdate, дабы шифровать кусками по, например, BUFFER_SIZE. Это сообщение отредактировал(а) shutffl - 7.11.2012, 16:05
--------------------
shadowmoon
|