#include <stdio.h>
#include <stdlib.h>

#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs12.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/md5.h>
#include <openssl/rc4.h>
#include <iostream>

using namespace std;
#define MAX_PATH 512

#define BUFLEN 2048
void DoEncrypt(const char* srcfile, const char* enc_file)
{
char mykey[EVP_MAX_KEY_LENGTH] = "this's my key";
char iv[EVP_MAX_IV_LENGTH] = "my iv";
char ciphertext[BUFLEN*2] = {0};
char plaintext[BUFLEN] = {0};
FILE* fpread = fopen(srcfile, "rb");
int iReadLen = 0;
if (NULL == fpread)
{
cout<<"do encrypt read src file fail" <<endl;
return;
}
FILE* fpwrite = fopen(enc_file, "w+");
if (NULL == fpwrite)
{
cout<<"enc_file to create fail" <<endl;
fclose(fpread);
return;
}
const EVP_CIPHER* cipherType = EVP_des_ede3_ecb();
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);

int out_len;
EVP_EncryptInit(&ctx, cipherType, (const unsigned char*)mykey, (const unsigned char*)iv);
while ( (iReadLen = fread(plaintext, 1, BUFLEN, fpread)) > 0 )
{
memset(ciphertext, 0x00, sizeof(ciphertext));
EVP_EncryptUpdate(&ctx, (unsigned char*)ciphertext, &out_len, (const unsigned char*)plaintext, iReadLen);
fwrite(ciphertext, 1, out_len, fpwrite);
memset(plaintext, 0x00, sizeof(plaintext));
}
EVP_EncryptFinal(&ctx, (unsigned char*)ciphertext, &out_len);
fwrite(ciphertext, 1, out_len, fpwrite);
EVP_CIPHER_CTX_cleanup(&ctx);

fclose(fpread);
fclose(fpwrite);
cout<< "DoEncrypt finish" <<endl;
}
void DoDecrypt(const char* enc_file, const char* dec_file)
{
char mykey[EVP_MAX_KEY_LENGTH] = "this's my key";
char iv[EVP_MAX_IV_LENGTH] = "my iv";
char ciphertext[BUFLEN*2] = {0};
char plaintext[BUFLEN] = {0};
FILE* fpread = fopen(enc_file, "rb");
if (NULL == fpread)
{
cout<<"DoDecrypt enc file open fail" <<endl;
return;
}
FILE* fpwrite = fopen(dec_file, "w+");
if (NULL == fpwrite)
{
cout<< "DoDecrypt open dec file create fail" <<endl;
fclose(fpread);
return;
}

const EVP_CIPHER* cipherType = EVP_des_ede3_ecb();
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit(&ctx, (const EVP_CIPHER*)cipherType, (const unsigned char*)mykey, (const unsigned char*)iv);
int iReadLen, out_len;
while ( (iReadLen = fread(plaintext, 1, BUFLEN, fpread)) > 0 )
{
memset(ciphertext, 0x00, sizeof(ciphertext));
EVP_DecryptUpdate(&ctx, (unsigned char*)ciphertext, &out_len, (const unsigned char*)plaintext, iReadLen);
fwrite(ciphertext, 1, out_len, fpwrite);
memset(plaintext, 0x00, sizeof(plaintext));
}
EVP_DecryptFinal(&ctx, (unsigned char*)ciphertext, &out_len);
fwrite(ciphertext, 1, out_len, fpwrite);
EVP_CIPHER_CTX_cleanup(&ctx);

fclose(fpread);
fclose(fpwrite);
cout<< "DoDecrypt finished" <<endl;
}

int main(void)
{
const char* srcfile = "abc.txt";
const char* enc_file = "abc.txt.enc";
const char* dec_file = "abc.txt.dec";
DoEncrypt(srcfile, enc_file);
DoDecrypt(enc_file, dec_file);
return 0;
}