OpenSSL的AES通过使用C API执行副总裁CBC 256 [英] OpenSSL AES 256 CBC via EVP api in C

查看:315
本文介绍了OpenSSL的AES通过使用C API执行副总裁CBC 256的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我所试图做的事:
C编写一个程序,打开任意大小的文件,并读取其内容。一旦该内容被读它将在AES 256 CBC加密它们和密文保存到称为密文的文件。一旦被保存,将关闭这两个文件。然后将打开从刚保存的文件密文和解密的密文,并将其保存到一个名为解密的文件。

我的问题:
它似乎永远解密我的密文。我得到的垃圾,我不知道我做错了。请帮助。

 的#include<&string.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;的OpenSSL / evp.h>
#包括LT&;的OpenSSL / aes.h>空加密(FILE * IFP,FILE * OFP)
{
  //获取文件大小
  fseek的(IFP,0L,SEEK_END);
  INT FSIZE = FTELL(IFP);
  //设置恢复正​​常
  fseek的(IFP,0L,SEEK_SET);  INT outLen1 = 0; INT outLen2 = 0;
  无符号字符* INDATA =的malloc(FSIZE);
  无符号字符* outdata =的malloc(FSIZE * 2);
  unsigned char型ckey [] =thiskeyisverybad;
  unsigned char型IVEC [] =dontusethisinput;  //读取文件
  FREAD(INDATA,sizeof的(炭),FSIZE,IFP); //读取整个文件  //设置加密
  EVP_C​​IPHER_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的(炭),FSIZE,OFP);
}无效解密(FILE * IFP,FILE * OFP)
{
  //获取文件大小
  fseek的(IFP,0L,SEEK_END);
  INT FSIZE = FTELL(IFP);
  //设置恢复正​​常
  fseek的(IFP,0L,SEEK_SET);  INT outLen1 = 0; INT outLen2 = 0;
  无符号字符* INDATA =的malloc(FSIZE);
  无符号字符* outdata =的malloc(FSIZE * 2);
  unsigned char型ckey [] =thiskeyisverybad;
  unsigned char型IVEC [] =dontusethisinput;  //读取文件
  FREAD(INDATA,sizeof的(炭),FSIZE,IFP); //读取整个文件  //设置解密
  EVP_C​​IPHER_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的(炭),FSIZE,OFP);
}INT主(INT ARGC,CHAR *的argv [])
{
  FILE * FIN,* fOUT的;  在fIN =的fopen(plain.txt,RB); //文件进行加密;纯文本
  fOUT的FOPEN =(cyphertext.txt,世行); //文件将被写入;密文
  加密(FIN,fOUT的);  FCLOSE(FIN);
  FCLOSE(fOUT的);  //现在解密文件
  在fIN = FOPEN(cyphertext.txt,RB); //文件将被写入;密文
  fOUT的FOPEN =(decrypted.txt,世行); //文件将被写入;密文
  解密(FIN,fOUT的);  FCLOSE(FIN);
  FCLOSE(fOUT的);  返回0;
}

注:可能有一些拼写错误。
编辑:好像我做了密钥和IV,一个错误这两者都是128位,我尝试使用256位的CBC。这是我的问题,似乎一旦我把它改为工作

  EVP_aes_128_cbc()


解决方案

下面是我对你的code版本。当然,我更喜欢它,但我提供它只是作为一种替代。请注意,完全没有错误检查:真正的code将有它

的#include<&string.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;的OpenSSL / evp.h>
#包括LT&;的OpenSSL / aes.h>的#ifndef TRUE
的#define TRUE 1
#万一FALSE的#ifndef
#定义FALSE 0
#万一
/ **
 *加密或解密,这取决于标志should_encrypt
 * /
无效en_de_crypt(INT should_encrypt,FILE * IFP,FILE * OFP,无符号字符* ckey,无符号字符* IVEC){    const的无符号BUFSIZE = 4096;
    无符号字符* read_buf =的malloc(BUFSIZE);
    无符号字符* cipher_buf;
    无符号的块大小;
    诠释out_len;
    EVP_C​​IPHER_CTX CTX;    EVP_C​​ipherInit(安培; CTX,EVP_aes_256_cbc(),ckey,IVEC,should_encrypt);
    块大小= EVP_C​​IPHER_CTX_block_size(安培; CTX);
    cipher_buf =的malloc(BUFSIZE +块大小);    而(1){        //读取数据块,直到EOF。更新与每个读了加密。        INT numRead = FREAD(read_buf,sizeof的(无符号字符),BUFSIZE,IFP);
        EVP_C​​ipherUpdate(安培; CTX,cipher_buf,&安培; out_len,read_buf,numRead);
        FWRITE(cipher_buf,sizeof的(无符号字符),out_len,OFP);
        如果(numRead&下; BUFSIZE){// EOF
            打破;
        }
    }    //现在密文的最后块写出来。    EVP_C​​ipherFinal(安培; CTX,cipher_buf,&安培; out_len);
    FWRITE(cipher_buf,sizeof的(无符号字符),out_len,OFP);    //空闲内存    免费(cipher_buf);
    免费(read_buf);
}INT主(INT ARGC,CHAR *的argv []){    unsigned char型ckey [] =thiskeyisverybad;
    unsigned char型IVEC [] =dontusethisinput;
    FILE * FIN,* fOUT的;    如果(的argc!= 2){
        的printf(用法:其中;可执行> /路径/到/文件/ EXE);
        返回-1;
    }    //首先加密的文件    在fIN =的fopen(plain.txt,RB); //文件进行加密;纯文本
    fOUT的FOPEN =(cyphertext.txt,世行);要被写入//文件;密文    en_de_crypt(TRUE,FIN,fOUT的,ckey,IVEC);    FCLOSE(FIN);
    FCLOSE(fOUT的);    //现在解密文件    在fIN =的fopen(cyphertext.txt,RB);要读取//文件;密文
    fOUT的FOPEN =(decrypted.txt,世行);要被写入//文件;密文    en_de_crypt(FALSE,FIN,fOUT的,ckey,IVEC);    FCLOSE(FIN);
    FCLOSE(fOUT的);    返回0;
}

What I am trying to do: Write a program in C that opens a file of arbitrary size and reads its contents. Once The contents are read it will encrypt them in AES 256 CBC and save the ciphertext to a file called ciphertext. Once this is saved it will close both files. Then will open the cipher text from the file that was just saved and decrypt the cipher text and save it to a file called decrypted.

My Problem: It seems to never decrypt my cipher text. I get garbage, I have no idea what I am doing wrong. Please help.

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

Note: there may be some misspellings. EDIT: Seems Like I made a mistake with the key and IV, both of which are 128 bit and I am trying to use the 256 bit CBC. This was my problem, seems to work once I changed it to

EVP_aes_128_cbc()

解决方案

Here is my version of your code. Naturally I like it better, but I offer it just as an alternative. Note the complete absence of error checking: real code would have it.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif


/**
 * Encrypt or decrypt, depending on flag 'should_encrypt'
 */
void en_de_crypt(int should_encrypt, FILE *ifp, FILE *ofp, unsigned char *ckey, unsigned char *ivec) {

    const unsigned BUFSIZE=4096;
    unsigned char *read_buf = malloc(BUFSIZE);
    unsigned char *cipher_buf;
    unsigned blocksize;
    int out_len;
    EVP_CIPHER_CTX ctx;

    EVP_CipherInit(&ctx, EVP_aes_256_cbc(), ckey, ivec, should_encrypt);
    blocksize = EVP_CIPHER_CTX_block_size(&ctx);
    cipher_buf = malloc(BUFSIZE + blocksize);

    while (1) {

        // Read in data in blocks until EOF. Update the ciphering with each read.

        int numRead = fread(read_buf, sizeof(unsigned char), BUFSIZE, ifp);
        EVP_CipherUpdate(&ctx, cipher_buf, &out_len, read_buf, numRead);
        fwrite(cipher_buf, sizeof(unsigned char), out_len, ofp);
        if (numRead < BUFSIZE) { // EOF
            break;
        }
    }

    // Now cipher the final block and write it out.

    EVP_CipherFinal(&ctx, cipher_buf, &out_len);
    fwrite(cipher_buf, sizeof(unsigned char), out_len, ofp);

    // Free memory

    free(cipher_buf);
    free(read_buf);
}

int main(int argc, char *argv[]) {

    unsigned char ckey[] = "thiskeyisverybad";
    unsigned char ivec[] = "dontusethisinput";
    FILE *fIN, *fOUT;

    if (argc != 2) {
        printf("Usage: <executable> /path/to/file/exe");
        return -1;
    }

    // First encrypt the file

    fIN = fopen("plain.txt", "rb"); //File to be encrypted; plain text
    fOUT = fopen("cyphertext.txt", "wb"); //File to be written; cipher text

    en_de_crypt(TRUE, fIN, fOUT, ckey, ivec);

    fclose(fIN);
    fclose(fOUT);

    //Decrypt file now

    fIN = fopen("cyphertext.txt", "rb"); //File to be read; cipher text
    fOUT = fopen("decrypted.txt", "wb"); //File to be written; cipher text

    en_de_crypt(FALSE, fIN, fOUT, ckey, ivec);

    fclose(fIN);
    fclose(fOUT);

    return 0;
}

这篇关于OpenSSL的AES通过使用C API执行副总裁CBC 256的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆