c - 调用 OpenSSL DES_cbc_encrypt() 时堆栈损坏

标签 c openssl des stack-corruption

这是使用 DES 加密 struct 的代码,然后在写入 File 后将其读回:

#include "openssl/des.h"
#include "openssl/conf.h"
#include "openssl/evp.h"
#include "openssl/err.h"
#include <stdio.h>


typedef struct MyStruct_t
{
        char m_Name[32];
        char m_ID[16];
} MyStruct;


uint8_t* __stdcall myStructToBytes(const MyStruct * const iMyStruct)
{
    const size_t len = sizeof(MyStruct;
    uint8_t *buffer = (uint8_t*) malloc(len);

    memcpy(buffer, iMyStruct, len);
    return buffer;
}

const int __stdcall encodeMyStructToFile(const char *sOutputFilename,
                                                         const char *sKey, const MyStruct *iStruct)
{
    DES_cblock key, iv;
    DES_key_schedule schedule;
    unsigned char *data = myStructToBytes((const MyStruct * const)iStruct);
    long len = sizeof(MyStruct);
    int ret = 0;

    memcpy(key, &sKey[0], 8);
    memcpy(iv, &sKey[0], 8);
    DES_set_odd_parity(&key);
    ret = DES_set_key_checked(&key, &schedule);

    if(ret == 0) {
        FILE *write_ptr;
        unsigned char *encrypted = (unsigned char *)malloc(len);
        DES_cbc_encrypt(data, encrypted, len, &schedule, &iv, DES_ENCRYPT);

        // Write encrypted data to file...
        fopen_s(&write_ptr, sOutputFilename, "wb");
        fwrite(encrypted, len, 1, write_ptr);
        fclose(write_ptr);
        free(encrypted);
    }
    free(data);

    return ret;
}


const int __stdcall decodeMyStructFromFile(const char *sInputFilename,
           const char *sKey, MyStruct *oStruct)
{
    int ret = 0;
    DES_cblock key, iv;
    DES_key_schedule schedule;
    FILE *read_ptr;
    long len = 0;
    unsigned char *encrypted = NULL;

    // Read encrypted data from file...
    fopen_s(&read_ptr, sInputFilename, "rb");
    ret = fseek(read_ptr, 0L, SEEK_END);
    len = ftell(read_ptr);
    rewind(read_ptr);
    encrypted = (unsigned char *)malloc(len);
    fread(encrypted, len, 1, read_ptr);
    fclose(read_ptr);

    // Perform decryption...
    memcpy(key, &sKey[0], 8);
    memcpy(iv, &sKey[0], 8);
    DES_set_odd_parity(&key);
    ret = DES_set_key_checked(&key, &schedule);

    if(ret == 0) {
        DES_cbc_encrypt(encrypted, (unsigned char *)oStruct, len, &schedule, &iv, DES_DECRYPT);
    }
    free(encrypted);

    return ret;
}

int main() {
    MyStruct tMyStruct;
    MyStruct tMyStruct1;
    char outputFilename[] = "abcd.bin";
    char key[] = "key_to_file";

    memset(&tMyStruct, 0, sizeof(MyStruct));
    memcpy_s(tMyStruct.m_Name, 256, "Hello", 5);
    memcpy_s(tMyStruct.m_ID, 32, "1234567890", 10);

    encodeMyStructToFile((const char *)outputFilename, (const char *)key, (const MyStruct * const)&tMyStruct);

    decodeLicenseStructFromFile(outputFilename, key, &tMyStruct1);


    return 0;
}

不知何故,我在加密和解密函数的调试器中收到堆栈损坏错误。我追踪了 DES_cbc_encrypt() 周围的问题。我究竟做错了什么?我正在使用 OpenSSL 的编译二进制文件:64 位 上的 openssl-1.1.0e-vs2012

最佳答案

我回到这里的原因是因为我注意到(尽管无法从示例代码中生成),DES_cbc_encrypt()DES_cbc_decrypt() 都起作用期望8 字节对齐 输入。因此,在不幸的情况下,如果此处的结构体大小不是 8 的倍数,DES_cbc_encrypt() 将写入超出缓冲区末尾的内容,从而出现明显的堆栈损坏。虽然,当没有显式禁用填充时,sizeof()仍然返回成员大小的总和,所以我理解这种情况是应用程序程序员的任务。也许有人可以对此进行更多阐述。

关于c - 调用 OpenSSL DES_cbc_encrypt() 时堆栈损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42897556/

相关文章:

c - 使用 realloc 在 C 中设置动态 vector 时出现未处理的异常

c - SDL:无法翻转多个表面

OpenSSL 在 aes 加密中填充 key ?

用于清理 openssl EVP_PKEY 私钥内存的 C 代码

swift - 如何在 Swift 3 中生成 DES key

c++ - 为什么 clang 不像 #define 那样优化全局常量?

c - 得到 "error: undeclared here (not in a function)"和 void * 变量数组

cryptography - OpenSSL gost 引擎问题

JAVA - 解密 "DES"加密随机数

c++ - 程序中不明确的指针缺陷