调用OpenSSL时堆栈损坏DES_cbc_encrypt()

时间:2017-03-20 07:02:02

标签: c openssl des stack-corruption

这是使用struct加密DES的代码,然后在写入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()周围的问题。我究竟做错了什么?我在Open {openssl-1.1.0e-vs2012上使用已编译的二进制文件:64-bit

1 个答案:

答案 0 :(得分:0)

为什么我回到这里的原因是因为我注意到(尽管不能从示例代码中生成),DES_cbc_encrypt()DES_cbc_decrypt()函数都期望8-byte aligned输入。因此,在不幸的情况下,如果这里的结构大小不是8的倍数,DES_cbc_encrypt()将写入超过缓冲区的末尾,因此明显的堆栈损坏。虽然,当没有明确禁用填充时,sizeof()仍然返回成员大小的总和,所以我理解这种情况是应用程序员的任务。也许有人可以点亮这个。