通过C中的EVP api实现OpenSSL AES 256 CBC
我想做什么: 用C编写一个程序,打开任意大小的文件并读取其内容。一旦内容被读取,它将在AES 256 CBC中对其进行加密,并将密文保存到名为ciphertext的文件中。保存后,它将关闭两个文件。然后将打开刚刚保存的文件中的密码文本,解密密码文本并将其保存到名为decrypted的文件中 我的问题: 它似乎永远不会解密我的密文。我收到垃圾,我不知道我做错了什么。请帮忙通过C中的EVP api实现OpenSSL AES 256 CBC,c,encryption,cryptography,openssl,aes,C,Encryption,Cryptography,Openssl,Aes,我想做什么: 用C编写一个程序,打开任意大小的文件并读取其内容。一旦内容被读取,它将在AES 256 CBC中对其进行加密,并将密文保存到名为ciphertext的文件中。保存后,它将关闭两个文件。然后将打开刚刚保存的文件中的密码文本,解密密码文本并将其保存到名为decrypted的文件中 我的问题: 它似乎永远不会解密我的密文。我收到垃圾,我不知道我做错了什么。请帮忙 #include <string.h> #include <stdio.h> #include <
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
void encrypt(FILE *ifp, FILE *ofp)
{
//Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
//set back to normal
fseek(ifp, 0L, SEEK_SET);
int outLen1 = 0; int outLen2 = 0;
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize*2);
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
//Read File
fread(indata,sizeof(char),fsize, ifp);//Read Entire File
//Set up encryption
EVP_CIPHER_CTX ctx;
EVP_EncryptInit(&ctx,EVP_aes_256_cbc(),ckey,ivec);
EVP_EncryptUpdate(&ctx,outdata,&outLen1,indata,fsize);
EVP_EncryptFinal(&ctx,outdata,&outLen2);
fwrite(outdata,sizeof(char),fsize,ofp);
}
void decrypt(FILE *ifp, FILE *ofp)
{
//Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
//set back to normal
fseek(ifp, 0L, SEEK_SET);
int outLen1 = 0; int outLen2 = 0;
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize*2);
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
//Read File
fread(indata,sizeof(char),fsize, ifp);//Read Entire File
//setup decryption
EVP_CIPHER_CTX ctx;
EVP_DecryptInit(&ctx,EVP_aes_256_cbc(),ckey,ivec);
EVP_DecryptUpdate(&ctx,outdata,&outLen1,indata,fsize);
EVP_DecryptFinal(&ctx,outdata,&outLen2);
fwrite(outdata,sizeof(char),fsize,ofp);
}
int main(int argc, char *argv[])
{
FILE *fIN, *fOUT;
fIN = fopen("plain.txt", "rb");//File to be encrypted; plain text
fOUT = fopen("cyphertext.txt", "wb");//File to be written; cipher text
encrypt(fIN, fOUT);
fclose(fIN);
fclose(fOUT);
//Decrypt file now
fIN = fopen("cyphertext.txt", "rb");//File to be written; cipher text
fOUT = fopen("decrypted.txt", "wb");//File to be written; cipher text
decrypt(fIN,fOUT);
fclose(fIN);
fclose(fOUT);
return 0;
}
此代码有效,如果任何人对如何更干净或更高效有一些建议,请发表评论
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
void encrypt(FILE *ifp, FILE *ofp)
{
//Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
//set back to normal
fseek(ifp, 0L, SEEK_SET);
int outLen1 = 0; int outLen2 = 0;
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize*2);
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
//Read File
fread(indata,sizeof(char),fsize, ifp);//Read Entire File
//Set up encryption
EVP_CIPHER_CTX ctx;
EVP_EncryptInit(&ctx,EVP_aes_128_cbc(),ckey,ivec);
EVP_EncryptUpdate(&ctx,outdata,&outLen1,indata,fsize);
EVP_EncryptFinal(&ctx,outdata + outLen1,&outLen2);
fwrite(outdata,sizeof(char),outLen1 + outLen2,ofp);
}
void decrypt(FILE *ifp, FILE *ofp)
{
//Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
//set back to normal
fseek(ifp, 0L, SEEK_SET);
int outLen1 = 0; int outLen2 = 0;
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize);
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
//Read File
fread(indata,sizeof(char),fsize, ifp);//Read Entire File
//setup decryption
EVP_CIPHER_CTX ctx;
EVP_DecryptInit(&ctx,EVP_aes_128_cbc(),ckey,ivec);
EVP_DecryptUpdate(&ctx,outdata,&outLen1,indata,fsize);
EVP_DecryptFinal(&ctx,outdata + outLen1,&outLen2);
fwrite(outdata,sizeof(char),outLen1 + outLen2,ofp);
}
int main(int argc, char *argv[])
{
if(argc != 2){
printf("Usage: <executable> /path/to/file/exe");
return -1;
}
FILE *fIN, *fOUT;
fIN = fopen("plain.txt", "rb");//File to be encrypted; plain text
fOUT = fopen("cyphertext.txt", "wb");//File to be written; cipher text
encrypt(fIN, fOUT);
fclose(fIN);
fclose(fOUT);
//Decrypt file now
fIN = fopen("cyphertext.txt", "rb");//File to be written; cipher text
fOUT = fopen("decrypted.txt", "wb");//File to be written; cipher text
decrypt(fIN,fOUT);
fclose(fIN);
fclose(fOUT);
return 0;
}
#包括
#包括
#包括
#包括
#包括
无效加密(文件*ifp,文件*ofp)
{
//获取文件大小
fseek(ifp,0L,SEEK_END);
int fsize=ftell(ifp);
//恢复正常
fseek(ifp、0L、SEEK\u集);
int-outLen1=0;int-outLen2=0;
无符号字符*indata=malloc(fsize);
无符号字符*outdata=malloc(fsize*2);
无符号字符ckey[]=“thiskeyisverybad”;
无符号字符ivec[]=“dontusethisinput”;
//读取文件
fread(indata,sizeof(char),fsize,ifp);//读取整个文件
//设置加密
执行副总裁;
EVP_EncryptInit(&ctx,EVP_aes_128_cbc(),ckey,ivec);
EVP_EncryptUpdate(ctx、outdata和outLen1、indata、fsize);
EVP_EncryptFinal(和ctx、outdata+outLen1和outLen2);
fwrite(outdata,sizeof(char),outLen1+outLen2,ofp);
}
无效解密(文件*ifp,文件*ofp)
{
//获取文件大小
fseek(ifp,0L,SEEK_END);
int fsize=ftell(ifp);
//恢复正常
fseek(ifp、0L、SEEK\u集);
int-outLen1=0;int-outLen2=0;
无符号字符*indata=malloc(fsize);
无符号字符*outdata=malloc(fsize);
无符号字符ckey[]=“thiskeyisverybad”;
无符号字符ivec[]=“dontusethisinput”;
//读取文件
fread(indata,sizeof(char),fsize,ifp);//读取整个文件
//设置解密
执行副总裁;
EVP_DecryptInit(&ctx,EVP_aes_128_cbc(),ckey,ivec);
EVP_DecryptUpdate(ctx、outdata和outLen1、indata、fsize);
执行副总裁(ctx、outdata+outLen1和outLen2);
fwrite(outdata,sizeof(char),outLen1+outLen2,ofp);
}
int main(int argc,char*argv[])
{
如果(argc!=2){
printf(“用法:/path/to/file/exe”);
返回-1;
}
文件*fIN,*fOUT;
fIN=fopen(“plain.txt”、“rb”);//要加密的文件;纯文本
fOUT=fopen(“cyphertext.txt”,“wb”);//要写入的文件;密文
加密(fIN、fOUT);
财务总监(财务);
fclose(fOUT);
//现在解密文件
fIN=fopen(“cyphertext.txt”,“rb”);//要写入的文件;密文
fOUT=fopen(“decrypted.txt”,“wb”);//要写入的文件;密文
解密(fIN,fOUT);
财务总监(财务);
fclose(fOUT);
返回0;
}
同样根据这篇文章,EVPAPI将处理任意大小的输入
这是我的代码版本。当然,我更喜欢它,但我提供它只是作为一种选择。请注意,完全没有错误检查:真正的代码会有错误检查
#包括
#包括
#包括
#包括
#包括
#如果是真的
#定义真1
#恩迪夫
#ifndef FALSE
#定义FALSE 0
#恩迪夫
/**
*加密或解密,取决于标志“应加密”
*/
void en_de_crypt(int应加密,FILE*ifp,FILE*ofp,unsigned char*ckey,unsigned char*ivec){
const unsigned BUFSIZE=4096;
无符号字符*read_buf=malloc(BUFSIZE);
无符号字符*cipher_buf;
无符号块大小;
int out_len;
执行副总裁;
EVP_CipherInit(&ctx,EVP_aes_256_cbc(),ckey,ivec,应加密);
blocksize=EVP\u CIPHER\u CTX\u block\u size(&CTX);
cipher_buf=malloc(BUFSIZE+blocksize);
而(1){
//以块形式读取数据,直到EOF。每次读取时更新加密。
int numRead=fread(read_buf,sizeof(无符号字符),BUFSIZE,ifp);
执行副总裁密码更新(ctx、密码、输出、读取、numRead);
fwrite(cipher_buf,sizeof(unsigned char),out_len,of p);
if(numRead
您认为输出文件的长度与输入文件的长度相同的假设是错误的。另外,您确定您的C编译器支持动态数组吗?通常情况下,您必须malloc
indata和outdata.ok,那么如果我说使输出文件的大小至少为输入文件的2倍,那么我就安全了?还是有更好的办法?另外,就动态数组而言,我不确定我的编译器是否会这样做(代码块默认为GCC)。不管怎样,我做了malloc(fsize)和malloc(fsize*2)。它仍然会给我垃圾数据。您的EVP_*Update()方法正在覆盖outdata数组的开头。您需要类似于EVP\u EncryptFinal(&ctx、outdata+outLen1和outLen2)的东西代码>。解密也是一样。不完全确定它是如何工作的,第二个参数unsigned char*和i不是吗
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
void encrypt(FILE *ifp, FILE *ofp)
{
//Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
//set back to normal
fseek(ifp, 0L, SEEK_SET);
int outLen1 = 0; int outLen2 = 0;
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize*2);
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
//Read File
fread(indata,sizeof(char),fsize, ifp);//Read Entire File
//Set up encryption
EVP_CIPHER_CTX ctx;
EVP_EncryptInit(&ctx,EVP_aes_128_cbc(),ckey,ivec);
EVP_EncryptUpdate(&ctx,outdata,&outLen1,indata,fsize);
EVP_EncryptFinal(&ctx,outdata + outLen1,&outLen2);
fwrite(outdata,sizeof(char),outLen1 + outLen2,ofp);
}
void decrypt(FILE *ifp, FILE *ofp)
{
//Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
//set back to normal
fseek(ifp, 0L, SEEK_SET);
int outLen1 = 0; int outLen2 = 0;
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize);
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
//Read File
fread(indata,sizeof(char),fsize, ifp);//Read Entire File
//setup decryption
EVP_CIPHER_CTX ctx;
EVP_DecryptInit(&ctx,EVP_aes_128_cbc(),ckey,ivec);
EVP_DecryptUpdate(&ctx,outdata,&outLen1,indata,fsize);
EVP_DecryptFinal(&ctx,outdata + outLen1,&outLen2);
fwrite(outdata,sizeof(char),outLen1 + outLen2,ofp);
}
int main(int argc, char *argv[])
{
if(argc != 2){
printf("Usage: <executable> /path/to/file/exe");
return -1;
}
FILE *fIN, *fOUT;
fIN = fopen("plain.txt", "rb");//File to be encrypted; plain text
fOUT = fopen("cyphertext.txt", "wb");//File to be written; cipher text
encrypt(fIN, fOUT);
fclose(fIN);
fclose(fOUT);
//Decrypt file now
fIN = fopen("cyphertext.txt", "rb");//File to be written; cipher text
fOUT = fopen("decrypted.txt", "wb");//File to be written; cipher text
decrypt(fIN,fOUT);
fclose(fIN);
fclose(fOUT);
return 0;
}