我试图解密我最初使用openssl加密的文件:
#include <stdio.h>
#include <openssl/aes.h>
#include <string.h>
#include <stdlib.h>
const static unsigned char aes_key[]={"passwordpasswor"}; //15 characters + \0
int main(int argc, char *argv[]) {
if (argc>1) {
if (strcmp("encrypt",argv[1])==0) {
FILE *file;
file=fopen("file.txt","w+b");
unsigned char aes_input[]="#!/bin/bash\necho hello world\0";
unsigned char iv[AES_BLOCK_SIZE];
memset (iv,0x00,AES_BLOCK_SIZE);
unsigned char enc_out[sizeof(aes_input)];
unsigned char dec_out[sizeof(aes_input)];
AES_KEY enc_key,dec_key;
AES_set_encrypt_key(aes_key,sizeof(aes_key)*8,&enc_key);
AES_cbc_encrypt(aes_input,enc_out,sizeof(aes_input),&enc_key,iv,AES_ENCRYPT);
//decryption
memset(iv,0x00,AES_BLOCK_SIZE);
AES_set_decrypt_key(aes_key,sizeof(aes_key)*8,&dec_key);
AES_cbc_encrypt(enc_out,dec_out,sizeof(aes_input),&dec_key,iv,AES_DECRYPT);
//verify
printf("original %s\n",aes_input);
hex_print(enc_out, sizeof enc_out);
printf("sizeof enc_out is %i\n",sizeof(enc_out));
fwrite(enc_out,1,sizeof(enc_out),file);
printf("decrypted %s\n",dec_out);
}
if (strcmp("decrypt",argv[1])==0) {
printf("decrypt\n");
FILE *file;
char * ciphertext=0;
int file_length;
file=fopen("file.txt","r+b");
if (file) {
fseek (file,0,SEEK_END);
file_length= ftell(file);
fseek(file,0,SEEK_SET);
ciphertext=malloc(file_length);
if (ciphertext)
fread(ciphertext,1,file_length,file);
fclose(file);
}
//printf("ciphertext is %s\n",ciphertext);
//begin decryption
AES_KEY dec_key;
unsigned char enc_out[sizeof(ciphertext)];
unsigned char iv[AES_BLOCK_SIZE];
memset (iv,0x00,AES_BLOCK_SIZE);
AES_set_decrypt_key(aes_key,sizeof(aes_key)*8,&dec_key);
AES_cbc_encrypt(ciphertext,enc_out,sizeof(ciphertext),&dec_key,iv,AES_DECRYPT);
printf("original string is %s\n",enc_out);
}
}
return 0;
}
我也在加密函数中测试解密(在写入或读取文件之前直接解密)工作正常 然而,独立解密功能没有正确解密:
decrypt
original string is #!/bin/b�:�j�
由于解密工作正常,我假设它正在写入文件或从文件读取到导致这种乱码输出的字符串。
我做错了什么?
感谢。
答案 0 :(得分:1)
我有一些建议可能会有所帮助。最重要的是缓冲管理。
在第一部分中关闭加密文件。此外,您不需要null终止在引号中声明的字符串。例如,"hello world"
不是"hello world\0"
这将等同于您的cstring中的"hello world\0\0"
(它将被视为"hello world\0"
)。这更像是一种惯例。
制定条件if
和else if
,否则您将始终执行这两项检查。
我的理解是openssl的加密/解密函数处理缓冲区并使用sizeof(缓冲区)是不可靠的。我相信这些函数会返回输出的长度,因此您应该将其保存在变量中并使用它。
密钥带走,使用具有正确缓冲区大小的fwrite
函数,而不使用sizeof
。由于加密会为您提供伪随机字符,因此您可能在结束之前在缓冲区中使用空终止符。
以下是使用AES256 CBC的openssl手册的链接。我最近用它来加密和解密文件,它对我有用。我会提供一个代码片段,但它有点长。不幸的是,它使用的功能与您当前使用的功能不同。 https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption