通过C中的EVP api实现OpenSSL AES 256 CBC

通过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 <

我想做什么: 用C编写一个程序,打开任意大小的文件并读取其内容。一旦内容被读取,它将在AES 256 CBC中对其进行加密,并将密文保存到名为ciphertext的文件中。保存后,它将关闭两个文件。然后将打开刚刚保存的文件中的密码文本,解密密码文本并将其保存到名为decrypted的文件中

我的问题: 它似乎永远不会解密我的密文。我收到垃圾,我不知道我做错了什么。请帮忙

#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;
}