2011-12-16 34 views
3

私はopenssl c libを使用して3DESを使用してファイルの暗号化を暗号化しています。ファイルに数語が含まれていれば、ファイルは暗号化され解読されます。言い換えれば、それは間違って復号化される。どんな提案も親切です!openssl C++ 3DESファイル暗号化の復号化に失敗する

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

2048文字の前または後に失敗しますか? valgrindで既にメモリエラーをチェックしましたか? (http://valgrind.org/docs/manual/QuickStart.html) – Francois

答えて

1

fopenコールでは「w +」ではなく「w + b」が必要です。