C++ 使用AES“U 256”CBC return“解密文件;“解密错误”;错误

C++ 使用AES“U 256”CBC return“解密文件;“解密错误”;错误,c++,encryption,openssl,aes,C++,Encryption,Openssl,Aes,这是这个问题的后续问题: 我正试图解密一个文件。起初我把它读成ASCII文件而不是二进制文件。修复(我希望如此)并将其作为二进制文件读取时,我总是会遇到一个错误“bad decrypt”错误: 15208:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto\evp\evp_enc.c:570: 以下是我如何加密和解密的示例: 加密: Cipher cipher; ifstream f(

这是这个问题的后续问题:

我正试图解密一个文件。起初我把它读成ASCII文件而不是二进制文件。修复(我希望如此)并将其作为二进制文件读取时,我总是会遇到一个
错误“bad decrypt”
错误:

15208:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto\evp\evp_enc.c:570:
以下是我如何加密和解密的示例:

加密:

Cipher cipher;
ifstream f("d:/test.YML");
ofstream out("d:/temp.YML");
byte key[KEY_SIZE] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2};
byte iv[BLOCK_SIZE] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};

secure_string line;
secure_string temp;
while (getline(f, line)) {
    cipher.Encrypt(key, iv, line, temp);
    out << temp << endl;
}
密码;
ifstream f(“d:/test.YML”);
流出量(“d:/temp.YML”);
字节键[键大小]={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2};
字节iv[块大小]={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
固定线绳;
安全字符串温度;
while(getline(f,line)){
加密(密钥、iv、行、临时);

out您的代码中有许多问题……举几个例子:

  • “d:/temp.YML”)的流输出的
    应以二进制模式打开

  • out为什么只在4个流中的1个流中指定
    binary
    ?@rustyx:没错,我没有指定,但加密也需要它?在加密中,我将文件读为ascii@rustyx:我将它们全部更改为二进制并再次加密,但在解密时仍然存在相同的问题
    Cipher cipher;
        ifstream f("d:/temp.YML", ifstream::binary);
        ofstream out("d:/tempDecrypt.YML");
        byte key[KEY_SIZE] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2};
        byte iv[BLOCK_SIZE] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
    
        secure_string temp;
        vector<char> buffer(1024, 0);
    
        while (!f.eof()) {
            f.read(buffer.data(), buffer.size());
            streamsize dataSize = f.gcount();
            secure_string chunk = { buffer.begin(), buffer.begin() + dataSize };
    
            cipher.Decrypt(key, iv, chunk, temp);
        }
    
    #include <cstdint>
    #include <fstream>
    #include <openssl/conf.h>
    #include <openssl/evp.h>
    #include <openssl/err.h>
    #include <openssl/rand.h>
    #include <string.h>
    #include <stdio.h>
    
    static const size_t KEY_SIZE = 256 / 8, BLOCK_SIZE = 128 / 8;
    
    class AESBase {
    protected:
        const uint8_t *key, *iv;
        EVP_CIPHER_CTX *ctx;
        AESBase(const uint8_t *key, const uint8_t *iv) : key(key), iv(iv) {
            if (!(ctx = EVP_CIPHER_CTX_new()))
                handleErrors();
        }
        ~AESBase() {
            EVP_CIPHER_CTX_free(ctx);
        }
        static void handleErrors(void) {
            ERR_print_errors_fp(stderr);
            abort();
        }
    };
    
    class Encrypt : AESBase {
    public:
        Encrypt(const uint8_t *key, const uint8_t *iv) : AESBase(key, iv) {
            if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
                handleErrors();
        }
        int update(const char *plaintext, int plaintext_len, char *ciphertext) {
            int len;
            if (1 != EVP_EncryptUpdate(ctx, (uint8_t*)ciphertext, &len, (const uint8_t*)plaintext, plaintext_len))
                handleErrors();
            return len;
        }
        int final(char *ciphertext) {
            int len;
            if (1 != EVP_EncryptFinal_ex(ctx, (uint8_t*)ciphertext, &len))
                handleErrors();
            return len;
        }
    };
    
    class Decrypt : AESBase {
    public:
        Decrypt(const uint8_t *key, const uint8_t *iv) : AESBase(key, iv) {
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
                handleErrors();
        }
        int update(const char *ciphertext, int ciphertext_len, char *plaintext) {
            int len;
            if (1 != EVP_DecryptUpdate(ctx, (uint8_t*)plaintext, &len, (const uint8_t*)ciphertext, ciphertext_len))
                handleErrors();
            return len;
        }
        int final(char *plaintext) {
            int len;
            if (1 != EVP_DecryptFinal_ex(ctx, (uint8_t*)plaintext, &len))
                handleErrors();
            return len;
        }
    };
    
    void test_encrypt(const uint8_t *key, const char* in, const char* out) {
        std::ifstream fin(in, std::ios_base::binary);
        std::ofstream fout(out, std::ios_base::binary);
        uint8_t iv[BLOCK_SIZE];
        RAND_bytes(iv, sizeof(iv));
    
        char buf[1024], temp[sizeof(buf) + BLOCK_SIZE];
        Encrypt aes(key, iv);
        fout.write((char*)iv, sizeof(iv));
        while (fin) {
            fin.read(buf, sizeof(buf));
            int len = (int)fin.gcount();
            if (len <= 0)
                break;
            len = aes.update(buf, len, temp);
            fout.write(temp, len);
        }
        int len = aes.final(temp);
        fout.write(temp, len);
    }
    
    void test_decrypt(const uint8_t *key, const char* in, const char* out) {
        std::ifstream fin(in, std::ios_base::binary);
        std::ofstream fout(out, std::ios_base::binary);
        uint8_t iv[BLOCK_SIZE];
        fin.read((char*)iv, sizeof(iv));
    
        char buf[1024], temp[sizeof(buf) + BLOCK_SIZE];
        Decrypt aes(key, iv);
        while (fin) {
            fin.read(buf, sizeof(buf));
            int len = (int)fin.gcount();
            if (len <= 0)
                break;
            len = aes.update(buf, len, temp);
            fout.write(temp, len);
        }
        int len = aes.final(temp);
        fout.write(temp, len);
    }
    
    int main()
    {
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
        OPENSSL_config(NULL);
    
        uint8_t key[KEY_SIZE] = { 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2 };
        test_encrypt(key, "main.cpp", "main.cpp.enc");
        test_decrypt(key, "main.cpp.enc", "main.cpp.txt");
    }