Поиск:

Ответ в темуСоздание новой темы Создание опроса
> OpenSSL, пример использования 
V
    Опции темы
shutffl
Дата 7.11.2012, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.