У меня есть один зашифрованный текст, iv и файл словаря, включающий пароли, один из которых использовался для получения ключа для расшифровки. Вот код C, использующий метод грубой силы. Проблема, с которой я сталкиваюсь, заключается в том, что она дает мне много расшифрованного текста, который невозможно прочитать. Я не понимаю, в чем проблема.
вот входные данные и метод:
- зашифрованный текст (в шестнадцатеричном формате. 32 байта): 42296c688fbb3172ad74b3be52f74511031d3bdbd6359308f0e262cbe8609dc6 * 1008 (in6) 100 шестнадцатеричный формат. 16 байт): 00112233445566778899aabbccddeeff
- Шифр aes-128-cb c используется для шифрования
- Пароль, используемый для шифрования открытого текста, - это английское sh слово
- Длина открытого текста составляет 21 байт (код ASCII) и используется заполнение PKCS # 5 (Подсказка. Таким образом, заполнение будет 11 байтов 0x0b)
Что у меня есть попробовал:
Используя эту функцию KeyDerive Я сгенерировал ключ для всех паролей в файле словаря ("words.txt") и всех сгенерированных ключей, которые я использовал в расшифровать функция. Теперь проблема в том, что для одного из сгенерированных ключей расшифровка должна работать !! Но здесь я получаю много нечитаемых / мусорных строк как расшифрованных !!
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
int KeyDerive(char * password, const char * cipher_name, const char * digest_name, unsigned char *key)
{
const EVP_CIPHER *cipher;
const EVP_MD *dgst;
unsigned char derived_key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
unsigned char *salt = NULL;
int key_size;
OpenSSL_add_all_algorithms();
cipher = EVP_get_cipherbyname(cipher_name);
if(!cipher) { fprintf(stderr, "no such cipher\n"); return 0; }
dgst = EVP_get_digestbyname(digest_name);
if(!dgst) { fprintf(stderr, "no such digest\n"); return 0; }
if(!(key_size=EVP_BytesToKey(cipher,dgst, salt,
(unsigned char *)password, strlen(password), 1, derived_key, iv))){
fprintf(stderr, "EVP_BytesToKey failed\n");
return 0;
}
memcpy(key, derived_key, key_size);
return 1;
}
void handleErrors(void)
{
ERR_print_errors_fp(stderr);
//abort();
}
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;
int len, flag, plaintext_len;
/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new()))
{
printf("err inside EVP_CIPHER_CTX_new");
handleErrors();
}
/*
* Initialise the decryption operation. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits
*/
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
{
printf("err inside EVP_DecryptInit_ex");
handleErrors();
}
//EVP_CIPHER_CTX_set_padding(ctx,1);
/*
* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary.
*/
if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
{
printf("err inside EVP_DecryptUpdate");
handleErrors();
}
plaintext_len = len;
/*
* Finalise the decryption. Further plaintext bytes may be written at
* this stage.
*/
if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
{
//printf("\nerr inside EVP_DecryptFinal_ex\n");
//handleErrors();
return -2;
}
else
{
plaintext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
}
int main (void)
{
char line[256];//each line assuming password in file
char keystring[256];//each line assuming key in file
const char * cipher_name = "aes-128-cbc";
const char * digest_name = "md5";
const int key_len = 16;//deriving key len
unsigned char key[key_len];
unsigned char ciphertext[32] =
{0x42,0x29,0x6C,0x68,0x8f,0xbb,0x31,0x72,0xad,0x74,0xb3,0xbe,0x52,0xf7,0x45,0x11,0x03,0x1d,0x3b,
0xdb,0xd6,0x35,0x93,0x08,0xf0,0xe2,0x62,0xcb,0xe8,0x60,0x9d,0xc6};
unsigned char iv[16] =
{0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
int decryptedtext_len;
unsigned char decryptedtext[32];
FILE *fptr,*fp,*fp_decrypt;
fptr = fopen("words.txt","r");
fp = fopen("keylist.txt", "w+");
fp_decrypt = fopen("decryptlist.txt", "wb+");
if(fptr == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
if(fp == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
int i = 1;
while (fgets(line, sizeof(line), fptr))
{
line[strcspn(line, "\n")] = 0; // removing newline if one is found
printf("for line %d guessed pwd is: %s \n",i,line);
printf("for line %d key is :",i);
if(!KeyDerive(line, cipher_name, digest_name, key)){
fprintf(stderr, "key derivation failed\n");
return 0;
}
i++;
for (int j=0; j<key_len; j++){
fprintf(fp,"%02x",key[j] );//store hex key in a file
printf("%02x", key[j]);
}
fprintf(fp,"\n");
printf("\n");
}
fclose(fptr);
fclose(fp);
fp = fopen("keylist.txt", "r");
while (fgets(keystring, sizeof(keystring), fp))
{
keystring[strcspn(keystring, "\n")] = 0; // removing newline if one is found
printf("%s\n", keystring);
decryptedtext_len = decrypt(ciphertext, 32, keystring, iv,decryptedtext);
if(decryptedtext_len==-2)
{
continue;
}
// decryptedtext[decryptedtext_len] = '\0';
fprintf(fp_decrypt,"%s",decryptedtext);
fprintf(fp_decrypt,"\n");
//printf("Decrypted text is :\n");
// printf("%s\n", decryptedtext);
}
fclose(fp_decrypt);
return 0;
}