AES CTR 256 Шифрование Режим работы на OpenSSL

Im new для OpenSSL, может ли кто-нибудь дать мне подсказку о том, как инициализировать режим AES CTR из файла C. Я знаю, что это подпись метода, но у меня возникают проблемы с параметрами, документации не так много, нет ясного примера, как сделать простое шифрование. Я был бы признателен, если бы кто-нибудь мог продемонстрировать призыв к этому методу. Заранее спасибо!

void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 

Привет Caf Я очень ценю ваш быстрый ответ, который был действительно полезен, и defenetly лучший пример, который я нашел в Интернете. Я пытаюсь открыть файл с неопределенной длиной, зашифровать его и записать другой файл с зашифрованным текстом, затем открыть зашифрованный файл и восстановить открытый текст. Мне нужно использовать файл значительного количества MB, потому что я хотел бы сравнить производительность процессора. Однако у меня все еще есть проблема при расшифровке. Как-то при расшифровке значительных файлов txt (1504 КБ) он не будет расшифровывать его полностью, и я получу его в открытом тексте, а другая половина все еще зашифрована. Я думаю, что это может быть связано с размером iv или способом, которым я звоню в счетчик. Вот что я имею до сих пор:

 #include  #include  #include  struct ctr_state { unsigned char ivec[16]; unsigned int num; unsigned char ecount[16]; }; FILE *fp; FILE *rp; FILE *op; size_t count; char * buffer; AES_KEY key; int bytes_read, bytes_written; unsigned char indata[AES_BLOCK_SIZE]; unsigned char outdata[AES_BLOCK_SIZE]; unsigned char ckey[] = "thiskeyisverybad"; // It is 128bits though.. unsigned char iv[8] = {0};//This should be generated by RAND_Bytes I will take into consideration your previous post struct ctr_state state; int init_ctr(struct ctr_state *state, const unsigned char iv[8]){ state->num = 0; memset(state->ecount, 0, 16); memset(state->ivec + 8, 0, 8); memcpy(state->ivec, iv, 8); } void encrypt(){ //Opening files where text plain text is read and ciphertext stored fp=fopen("input.txt","a+b"); op=fopen("output.txt","w"); if (fp==NULL) {fputs ("File error",stderr); exit (1);} if (op==NULL) {fputs ("File error",stderr); exit (1);} //Initializing the encryption KEY AES_set_encrypt_key(ckey, 128, &key); //Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext while (1) { init_ctr(&state, iv); //Counter call bytes_read = fread(indata, 1, AES_BLOCK_SIZE, fp); AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num); bytes_written = fwrite(outdata, 1, bytes_read, op); if (bytes_read < AES_BLOCK_SIZE) break; } fclose (fp); fclose (op); free (buffer); } void decrypt(){ //Opening files where text cipher text is read and the plaintext recovered rp=fopen("recovered.txt","w"); op=fopen("output.txt","a+b"); if (rp==NULL) {fputs ("File error",stderr); exit (1);} if (op==NULL) {fputs ("File error",stderr); exit (1);} //Initializing the encryption KEY AES_set_encrypt_key(ckey, 128, &key); //Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext while (1) { init_ctr(&state, iv);//Counter call bytes_read = fread(indata, 1, AES_BLOCK_SIZE, op); AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num); bytes_written = fwrite(outdata, 1, bytes_read, rp); if (bytes_read < AES_BLOCK_SIZE) break; } fclose (rp); fclose (op); free (buffer); } int main(int argc, char *argv[]){ encrypt(); //decrypt(); system("PAUSE"); return 0; } 

Каждая функция шифрования и дешифрования вызывается в разных прогонах, поэтому все инициализируется всегда с одинаковыми значениями. Еще раз спасибо за подсказки, которые вы можете предоставить мне заранее и с уважением !!!

Обычно вы собираетесь называть AES_ctr128_encrypt() несколько раз, чтобы отправить несколько сообщений с тем же ключом и IV, и счетчиком с приращением. Это означает, что вам нужно отслеживать значения «ivec», «num» и «ecount» между вызовами – поэтому создайте struct для их хранения и функцию инициализации:

 struct ctr_state { unsigned char ivec[16]; /* ivec[0..7] is the IV, ivec[8..15] is the big-endian counter */ unsigned int num; unsigned char ecount[16]; }; int init_ctr(struct ctr_state *state, const unsigned char iv[8]) { /* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the * first call. */ state->num = 0; memset(state->ecount, 0, 16); /* Initialise counter in 'ivec' to 0 */ memset(state->ivec + 8, 0, 8); /* Copy IV into 'ivec' */ memcpy(state->ivec, iv, 8); } 

Теперь, когда вы начинаете общаться с пунктом назначения, вам нужно создать IV для использования и инициализации счетчика:

 unsigned char iv[8]; struct ctr_state state; if (!RAND_bytes(iv, 8)) /* Handle the error */; init_ctr(&state, iv); 

Затем вам необходимо отправить 8-байтный IV в пункт назначения. Вам также потребуется инициализировать AES_KEY из ваших необработанных ключевых байтов:

 AES_KEY aes_key; if (!AES_set_encrypt_key(key, 128, &aes_key)) /* Handle the error */; 

Теперь вы можете начать шифрование данных и отправку их адресату с повторными вызовами AES_ctr128_encrypt() следующим образом:

 if (!AES_ctr128_encrypt(msg_in, msg_out, msg_len, &aes_key, state->ivec, state->ecount, &state->num)) /* Handle the error */; 

( msg_in – это указатель на буфер, содержащий сообщение с открытым текстом, msg_out – указатель на буфер, в котором должно быть зашифрованное сообщение, а msg_len – длина сообщения).

Расшифровка точно такая же, за исключением того, что вы не генерируете IV с помощью RAND_bytes() – вместо этого вы берете значение, данное вам другой стороной.

Важный:

  1. Не вызывайте init_ctr() более одного раза во время процесса шифрования. Счетчик и IV должны быть инициализированы один раз только до начала шифрования.

  2. Ни при каких обстоятельствах не возникает соблазн получить IV везде, кроме RAND_bytes() на стороне шифрования. Не устанавливайте его на фиксированное значение; не используйте хеш-функцию; не используйте имя получателя; не читайте его с диска. Сгенерируйте его с помощью RAND_bytes() и отправьте его в пункт назначения. Всякий раз, когда вы начинаете с нулевого счетчика, вы должны начать с совершенно нового IV, которого вы никогда раньше не использовали.

  3. Если вообще возможно, что вы будете отправлять 2 ** 64 байта без изменения ключа IV и / или, вам нужно будет проверить, что счетчик переполнен.

  4. Не пропускайте проверку ошибок. Если функция не работает, и вы игнорируете ее, вполне возможно (даже вероятно), что ваша система будет работать нормально, но фактически будет работать совершенно небезопасно.

Похоже, основная проблема с вашей тестовой программой заключается в том, что значения режима вызовов fopen неверны. Я думаю, вам нужно изменить ваши вызовы fopen в encrypt:

 fp=fopen("input.txt","rb"); op=fopen("output.txt","wb"); 

И те, в расшифровке:

 rp=fopen("recovered.txt","wb"); op=fopen("output.txt","rb"); 

Еще одна вещь, заслуживающая внимания, заключается в том, что ckey вероятно, должен быть объявлен как 32-байтовый (256-битный) буфер. Это правда, что 128-битное шифрование использует только 16 байт данных из ключа. Но функция OpenSSL AES_set_encrypt_key (по крайней мере, в используемой версии) читает 32 байта из этого буфера. Он использует только соответствующее количество байтов, но чтение происходит. Это означает, что если буфер составляет всего 16 байт и заканчивается в конце страницы, которая смежна с нечитаемой страницей в памяти, это приведет к нарушению доступа.

Ох, и я только заметил, что там есть посторонний звонок. free(buffer); вызов недействителен, поскольку буфер никогда не выделялся. Я понимаю, что ваш код – просто простой тест, но … ну, мы программисты и не можем помочь себе.

  • Как создать самозаверяющий сертификат с помощью SubjectAltName с помощью OpenSSL?
  • Постройте Multiarch OpenSSL на OS X
  • Расшифровка открытого ключа OpenSSL PEM Encoded RSA с Java?
  • Как читать файл .pem, чтобы получить закрытый и открытый ключ
  • Непосредственно считывать / записывать данные подтверждения с помощью памяти BIO
  • Ошибка: «недопустимое использование неполного типа» RSA {aka struct rsa_st} в OpenSSL 1.1.0
  • Генерация ключей шифрования / дешифрования Java openssl
  • unique_ptr и STSE_OF (X509) OpenSSL *
  • Как реализовать идентификацию имени сервера (SNI)
  • Преобразование pfx в pem с помощью openssl
  • Как создать самозаверяющий сертификат с openssl?
  • Interesting Posts

    Как отключить отправку поведения asp: ImageButton?

    Подключите две домашние сети через VPN

    как правильно реализовать Parcelable с ArrayList ?

    ShouldSerialize * () vs * Условный шаблон условной сериализации

    Как автоматически генерировать stacktrace, когда моя программа gcc C ++ вылетает

    Как установить выбранную опцию выпадающего списка с использованием углового JS

    NoClassDefFoundError: org / w3c / dom / ElementTraversal

    Возможно изменение Windows 8 "Горячие углы"

    Сохранение состояния активности Android с использованием состояния Save Instance

    Как Python 2 сравнивает строку и int? Почему списки сравниваются больше, чем числа, а кортежи – больше, чем списки?

    Диалоговое окно «Печать» запрашивает подтверждение при печати всего документа

    Элементы ListView не доступны для кликов. Зачем?

    Добавить признанное изображение в элементы wp_nav_menu

    Каков правильный способ использования printf для печати size_t?

    * .h или * .hpp для определения classов

    Давайте будем гением компьютера.