调用 OpenSSL DES_cbc_encrypt() 时堆栈损坏
Stack corruption upon calling OpenSSL DES_cbc_encrypt()
这是使用 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 使用已编译的二进制文件:openssl-1.1.0e-vs2012
on 64-bit
.
我之所以回到这里,是因为我注意到(虽然不能从示例代码中产生),DES_cbc_encrypt()
和 DES_cbc_decrypt()
函数都需要 8-byte aligned
输入。因此在不幸的情况下,如果这里的结构体的大小不是 8 的倍数,DES_cbc_encrypt()
将写入超过缓冲区的末尾,因此明显的堆栈损坏。虽然,当未明确禁用填充时,sizeof()
仍然是 returns 成员大小的总和,所以我理解这种情况是应用程序程序员的任务。也许有人可以对此进行更多阐述。
这是使用 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 使用已编译的二进制文件:openssl-1.1.0e-vs2012
on 64-bit
.
我之所以回到这里,是因为我注意到(虽然不能从示例代码中产生),DES_cbc_encrypt()
和 DES_cbc_decrypt()
函数都需要 8-byte aligned
输入。因此在不幸的情况下,如果这里的结构体的大小不是 8 的倍数,DES_cbc_encrypt()
将写入超过缓冲区的末尾,因此明显的堆栈损坏。虽然,当未明确禁用填充时,sizeof()
仍然是 returns 成员大小的总和,所以我理解这种情况是应用程序程序员的任务。也许有人可以对此进行更多阐述。