openssl c++ 3DES文件加密解密失败 [英] openssl c++ 3DES file encryption decryption fail

查看:115
本文介绍了openssl c++ 3DES文件加密解密失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用openssl c lib 3DES加密解密文件,如果文件包含几个字,文件会被加密和解密,但如果源纯文件包含更多字,则解密不正确.任何建议都会很友好!

I'm using openssl c lib to encrypt decrypt a file using 3DES, If the file contains a few words, the file will be encrypted and decrypted ok, But if the source plain file contains more words, it decrypted incorrectly. Any suggestions would be kind!

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

推荐答案

在 fopen 调用中需要w+b"而不是w+".

You need "w+b" instead of "w+" in your fopen calls.

这篇关于openssl c++ 3DES文件加密解密失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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