Шифрование и дешифрование с помощью C++

У меня есть буфер, в который я добавляю обычный текст. Я хочу использовать шифрование openssl AES для шифрования текста, затем расшифровать его и распечатать обратно на экране.

Код работает без ошибок.

#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string>
#include <openssl/aes.h>
using namespace std;

void main()
{

// Buffers
unsigned char inbuffer[1024];
unsigned char encryptedbuffer[1024];
unsigned char outbuffer[1024];


// CODE FOR ENCRYPTION
//--------------------
unsigned char oneKey[] = "abc";
AES_KEY key; 

AES_set_encrypt_key(oneKey,128,&key);
AES_set_decrypt_key(oneKey,128,&key);

//--------------------


string straa("hello world\n");
memcpy((char*)inbuffer,straa.c_str(),13);


printf("%s",inbuffer);
//this prints out fine

AES_encrypt(inbuffer,encryptedbuffer,&key);
//printf("%s",encryptedbuffer);
//this is expected to pring out rubbish, so is commented

AES_decrypt(encryptedbuffer,outbuffer,&key);
printf("%s",outbuffer);
//this is not pringint "hello world"

getchar();

}

Я знаю о том факте, что после помещения в новые буферы "encryptedbuffer" и "outbuffer" они не заканчиваются нулем "\0" , но даже в этом случае, распечатывая необработанные данные, я получаю мусор только после расшифровка. В конце расшифровки я предполагаю, что \0 также должен быть расшифрован, и поэтому printf должен печатать правильно.

Кто-нибудь знает, как заставить работать расшифровку?

Также есть идеи, как печатать буферы с помощью библиотек C++, может быть, cout, а не printf?


person Dani Marian Morar    schedule 30.01.2014    source источник
comment
Механизм, который вы используете для ключей, неверен. AES — это симметричный блочный алгоритм, для которого требуется ключ, соответствующий размеру блока. Решение в стиле PBE (шифрование на основе пароля) часто использует хеш-дайджест пароля соответствующего размера для создания ключа надлежащего размера (в данном случае 16 байт). Тот же пароль, хэшированный с помощью того же алгоритма, используется на стороне получателя для генерации идентичного симметричного ключа и выполнения расшифровки. Другими словами, ваш пароль не является ключом к шифру; его дайджест из алгоритма, известного обеим сторонам.   -  person WhozCraig    schedule 30.01.2014
comment
(1) Сделайте oneKey не менее 16 байт (сейчас это только 3 байта). Дополнительные байты будут игнорироваться. (2) Сделайте straa ровно 16 байт (сейчас только 12 или 13 байт). (3) Сбросьте ключ между вызовами AES_encrypt и AES_decrypt. (4) Рассмотрите возможность переключения на функции EVP_*, которые проще для новичка. См., например, симметричное шифрование и дешифрование EVP на вики OpenSSL. Используйте EVP_aes_128_ecb() в качестве шифра для эквивалентной программы.   -  person jww    schedule 30.01.2014
comment
оцените четкие инструкции! теперь все кажется более понятным! :) благодарю вас   -  person Dani Marian Morar    schedule 30.01.2014
comment
Здесь действительно отличные комментарии, спасибо.   -  person Charlie Schliesser    schedule 05.08.2014
comment
Вы не должны не использовать AES_encrypt и друзей. Вы должны использовать EVP_* функции. См. симметричное шифрование и дешифрование EVP на вики OpenSSL. На самом деле вам, вероятно, следует использовать шифрование с проверкой подлинности, поскольку оно обеспечивает как конфиденциальность, так и подлинность. См. Шифрование и дешифрование с проверкой подлинности EVP на вики OpenSSL.   -  person jww    schedule 15.05.2015


Ответы (1)


Я заметил пару возможных проблем:

  • Вызов AES_set_decrypt_key использует тот же key, что и предыдущий вызов, таким образом, перезаписывая значение ключа. Чтобы сделать оба вызова заранее, было бы необходимо использовать отдельный экземпляр ключа. В противном случае подождите, чтобы вызвать AES_set_decrypt_key, пока не будет выполнено шифрование.
  • Буфер ключей, переданный в AES_set_encrypt_key, должен иметь длину 16 байтов для разрядности 128. Как бы то ни было, он будет считывать 16 байтов, но их содержимое не определено.
person Mark Wilkins    schedule 30.01.2014
comment
добавление «AES_set_decrypt_key» после того, как я сделал шифрование, действительно сработало! 'printf(%s,outbuffer);' теперь распечатывает правильный привет, мир. Я действительно ценю простое, но эффективное решение. - person Dani Marian Morar; 30.01.2014
comment
Я рад, что у тебя все получилось. Обратите внимание, что размер буфера ключей по-прежнему должен составлять 16 байт. Нет никакой гарантии, что неопределенные 12 байтов, следующие за существующей переменной oneKey, останутся неизменными между двумя вызовами. - person Mark Wilkins; 30.01.2014
comment
@DaniMarianMorar прислушайся к предупреждению Марка. Ваш ключ должен иметь ширину 16 байт. Если это не так, библиотека OpenSSL будет вслепую обращаться ко всему, что находится в памяти после ключа, что является неопределенным поведением. Подумайте, какие гадости могут возникнуть из этого, если за этим последует ваш зашифрованный текстовый блок. - person WhozCraig; 30.01.2014
comment
Спасибо за предупреждения. Вы, ребята, говорите, что я должен установить unsigned char oneKey[] = "abc"; в unsigned char oneKey[] = "abcdefghijklmnop";, что составляет 16 байт? Это сработает?, еще раз спасибо - person Dani Marian Morar; 30.01.2014
comment
@DaniMarianMorar: Это одна из возможностей, и в данном случае ее будет достаточно, чтобы предотвратить неопределенное поведение. - person Mark Wilkins; 30.01.2014