Итак, у меня есть этот код, который в основном шифрует два текстовых сообщения, а затем пытается их расшифровать и распечатать. Проблема в том, что первое сообщение восстанавливается отлично, а второе - мусор. Я загрузил этот код с this tutorial, а затем модифицировал его для работы со строками вместо файлов как Мне нужно его для отправки зашифрованного текста поверх сокетов. Так что длина открытого текста не будет известна другой конечной точке, есть ли способ найти длину или мне придется как-то отправить длину открытого текста вместе с шифром?Шифрование и дешифрование AES CTR
Теперь, я думаю, что есть проблема в режиме разрыва дешифрования.
Кроме того, является основным() кодом права концептуально: шифрование сообщений с обновлением состояния, а затем сброс состояния и дешифрование сообщений с обновлением состояния?
И есть ли способ узнать фактическую длину шифрованного текста (а не буфера)?
Это всего лишь манекен, который я пытался понять, как работает AES CTR.
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/hmac.h>
#include <openssl/buffer.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
// Code example uses partail code from: http://stackoverflow.com/questions/3141860/aes-ctr-256-encryption-mode-of-operation-on-openssl
// Mostly in the ctr_ state, and init_ctr functions.
struct ctr_state
{
unsigned char ivec[AES_BLOCK_SIZE];
unsigned int num;
unsigned char ecount[AES_BLOCK_SIZE];
};
int init_ctr(struct ctr_state *state, const unsigned char iv[16])
{
/* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the
* first call. */
state->num = 0;
memset(state->ecount, 0, AES_BLOCK_SIZE);
/* Initialise counter in 'ivec' to 0 */
memset(state->ivec + 8, 0, 8);
/* Copy IV into 'ivec' */
memcpy(state->ivec, iv, 8);
}
void fencrypt(char* text, char* cipher, const unsigned char* enc_key, struct ctr_state* state)
{
AES_KEY key;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
int offset=0;
//Initializing the encryption KEY
if (AES_set_encrypt_key(enc_key, 128, &key) < 0)
{
fprintf(stderr, "Could not set encryption key.");
exit(1);
}
//Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext
while(1)
{
printf("while going\n");
memcpy(indata, text+offset, AES_BLOCK_SIZE);
AES_ctr128_encrypt(indata, outdata, AES_BLOCK_SIZE, &key, state->ivec, state->ecount, &state->num);
memcpy(cipher+offset, outdata, AES_BLOCK_SIZE);
offset=offset+AES_BLOCK_SIZE;
if (offset > strlen(text))
{
break;
}
}
}
void fdecrypt(char* cipher, char* text, const unsigned char* enc_key, struct ctr_state* state)
{
AES_KEY key;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
int offset=0;
//Initializing the encryption KEY
if (AES_set_encrypt_key(enc_key, 128, &key) < 0)
{
fprintf(stderr, "Could not set decryption key.");
exit(1);
}
//Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext
while(1)
{
memcpy(indata, cipher+offset, AES_BLOCK_SIZE);
//printf("%i\n", state.num);
AES_ctr128_encrypt(indata, outdata, AES_BLOCK_SIZE, &key, state->ivec, state->ecount, &state->num);
memcpy(text+offset, outdata, AES_BLOCK_SIZE);
offset=offset+AES_BLOCK_SIZE;
if (offset > strlen(cipher))
{
break;
}
}
}
int main(int argc, char *argv[])
{
unsigned char iv[AES_BLOCK_SIZE];
struct ctr_state state;
char* plain="quick brown fox jumped over the lazy dog what ";
char* plain2="a dog he is idiot who is the genius ";
char cipher[128];
char cipher2[128];
char recovered[128];
char recovered2[128];
const unsigned char* enc_key="123456789abcdef0";
if(!RAND_bytes(iv, AES_BLOCK_SIZE))
{
fprintf(stderr, "Could not create random bytes.");
exit(1);
}
init_ctr(&state, iv); //Counter call
printf("Plain text length:%lu\n",strlen(plain));
// BIO_dump_fp(stdout, plain, strlen(plain));
// printf("Plain text:%s\n",plain);
fencrypt(plain, cipher,enc_key,&state);
fencrypt(plain2, cipher2,enc_key,&state);
// cipher[strlen(plain)]='\0';
// BIO_dump_fp(stdout, cipher, strlen(plain));
init_ctr(&state, iv); //Counter call
fdecrypt(cipher,recovered,enc_key,&state);
fdecrypt(cipher2,recovered2,enc_key,&state);
// printf("Cipher text length:%lu\n",strlen(cipher));
printf("Recovered text:%s\n",recovered);
printf("Recovered text:%s\n",recovered2);
return 0;
}
Я понимаю, что вы говорите, и я знал, что раньше, но проблема (как я уже говорил в этом вопросе), я буду посылать сообщение зашифрованное в сети, так другая сторона не будет знать длину обычного текста, если я не отправлю длину отдельно. Итак, я ищу способ найти длину только от шифрования, как действительно реализуются схемы шифрования по сетям? – Wajahat
Barmak здесь правильно; нет способа определить длину из случайных данных (а выход AES выглядит как случайные данные). Не думайте об этом как о «передаче зашифрованных данных в сети». Подумайте об этом как о «отправке данных по сети». Почти все двоичные протоколы включают в себя поле длины. –
Хорошо, ваша точка зрения, поэтому, если я использую сокеты TCP-потока в C, могу ли я добавить длину полезной нагрузки в пакете (я знаю, что в заголовке IP есть поле длины), которое можно восстановить на другом конце? Как я буду это делать, извините, что я новичок в программировании сокетов. – Wajahat