首页 文章

OpenSSL AES 256 CBC通过EV中的EVP api

提问于
浏览
8

What I am trying to do: 用C编写程序,打开任意大小的文件并读取其内容 . 一旦读取内容,它将在AES 256 CBC中对它们进行加密,并将密文保存到名为密文的文件中 . 保存后,它将关闭这两个文件 . 然后将打开刚刚保存的文件中的密文并解密密文并将其保存到名为decrypted的文件中 .

My Problem: 似乎永远不会解密我的密文 . 我得到垃圾,我不知道我做错了什么 . 请帮忙 .

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

注意:可能会有一些拼写错误 . 编辑:似乎我用键和IV弄错了,两者都是128位,我试图使用256位CBC . 这是我的问题,一旦我改成它似乎工作

EVP_aes_128_cbc()

2 回答

  • 4

    这是我的代码版本 . 当然我更喜欢它,但我提供它作为替代品 . 注意完全没有错误检查:真正的代码会有它 .

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

    这段代码有效,如果有人对如何更清洁或更有效率有一些建议请发表评论 .

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

    另外根据这篇文章,EVP api将处理任意大小的输入

    AES Encryption- large files

相关问题