gpt4 book ai didi

c - ECB 和 CBC 的 OpenSSL EVP 解密失败但适用于 OFB

转载 作者:太空宇宙 更新时间:2023-11-04 02:24:00 30 4
gpt4 key购买 nike

对于具有 OFB 模式的 AES-128,我的代码解密并完美运行,但对于 ECB 和 CBC,即使我使用相同的 key 和相同的 IV,它也只是提供随机输出。

这是我的代码:

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
#define BUFFER_SIZE 4096
#define KEY_SIZE 16


int failed = 0;

void print_hex(char *s){
while(*s){
printf("%02x" , (unsigned int) *s++);
}
}

int min(int a , int b){
return a < b ? a : b;
}

void set_padding(unsigned char* array){
for(int i= 0 ; i < KEY_SIZE; ++i){
array[i] = ' ';
}
}

int handleErrors(void)
{
// ERR_print_errors_fp(stderr);
// abort();
failed = 1;
return -1;
}

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, unsigned char *ciphertext , char* mode)
{
EVP_CIPHER_CTX *ctx;

int len;

int ciphertext_len;

if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

if(strcmp(mode , "OFB") == 0){
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ofb(), NULL, key, iv))
handleErrors();
}
else{
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
handleErrors();
}
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
handleErrors();
ciphertext_len = len;

if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;

EVP_CIPHER_CTX_free(ctx);

return ciphertext_len;
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext , char* mode)
{
EVP_CIPHER_CTX *ctx;

int len;

int plaintext_len;

if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

if(strcmp(mode , "OFB") == 0){
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ofb(), NULL, key, iv))
handleErrors();
}
else{
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
handleErrors();
}
if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
handleErrors();
plaintext_len = len;

if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
plaintext_len += len;

EVP_CIPHER_CTX_free(ctx);

return plaintext_len;
}


void write_to_file(FILE* fd , unsigned char * hash , int size){
for(int i = 0; i < size; ++i){
fprintf(fd , "%02x" , hash[i]);
}
}

void encrypt_and_write(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, char* mode , FILE *fd){
unsigned char buffer[2 * BUFFER_SIZE];
int size = 0;
size = encrypt(plaintext , plaintext_len , key , iv , buffer , mode);
write_to_file(fd , buffer , size);
}

int main(int argc , char** argv){
FILE *plain_text , *crypto_text , *dictionary;
unsigned char plain_text_buffer[BUFFER_SIZE];
unsigned char crypto_text_buffer[2 * BUFFER_SIZE];
unsigned int plain_text_size = 0;
unsigned int crypto_text_size = 0;
unsigned char iv[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
unsigned char key[] = "\x73\x65\x63\x69\x6E\x66\x6F\x20\x20\x20\x20\x20\x20\x20\x20\x20";
memset(plain_text_buffer, 0, sizeof(plain_text_buffer));
memset(crypto_text_buffer, 0, sizeof(crypto_text_buffer));
if(argc < 4){
printf("Wrong number of arguments!\n");
return 0;
}
if(strcmp(argv[3] , "OFB") != 0 && strcmp(argv[3] , "ECB") != 0){
printf("Use OFB or ECB mode only!\n");
return 0;
}
plain_text = fopen(argv[1] , "r");
crypto_text = fopen(argv[2] , "r");
dictionary = fopen("word_dict.txt" , "r");
char c;
while((c = fgetc(plain_text)) != EOF){
plain_text_buffer[plain_text_size] = c;
++plain_text_size;
}
// encrypt_and_write(plain_text_buffer , plain_text_size , key , iv , argv[3] , crypto_text);
unsigned int hexa = 0;
while(fscanf(crypto_text , "%02x" , &hexa) != EOF){
crypto_text_buffer[crypto_text_size] = hexa;
++crypto_text_size;
}
char * line = NULL;
int attempts = 0;
int len = 0;
unsigned char decrypt_buffer[BUFFER_SIZE];
size_t size = 0;
while(getline(&line , &size , dictionary) != -1){
set_padding(key);
for(int i = 0; i < strlen(line); ++i){
if(line[i] != '\n' && line[i] != '\0'){
key[i] = line[i];
}
}
key[KEY_SIZE] = '\0';
decrypt(crypto_text_buffer , crypto_text_size , key , iv , decrypt_buffer , argv[3]);
if(failed == 0){
if(strcmp(plain_text_buffer , decrypt_buffer) == 0){
printf("%i " , attempts);
print_hex(key);
printf(" %s" , line);
break;
}
else
++attempts;
}
else
++attempts;
}
return 0;
}

我试图找出问题所在,但没有成功。它甚至适用于 OFB 模式下的 DES,但对于 ECB 和 CBC,它再次失败。

word_dict.txt 只是一个用于暴力破解 key 的文件。

最佳答案

您正在使用 EVP_EncryptInit_ex 进行解密例程;你应该使用 EVP_DecryptInit_ex。 OFB 是一种流密码,这意味着加密/解密例程非常相似。 ECB/CBC 不是这种情况,因为它们需要填充/取消填充例程。

请注意,您不应填充/取消填充一个键。如果您使用密码,则应该使用密码哈希,也称为基于密码的 key 派生函数。 OpenSSL 内置了对 PBKDF2 的支持。

关于c - ECB 和 CBC 的 OpenSSL EVP 解密失败但适用于 OFB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53690728/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com