【问题标题】:Stack around variable was corrupted变量周围的堆栈已损坏
【发布时间】:2014-09-11 18:14:31
【问题描述】:

我有以下程序,其中我使用密钥长度为 256 位的 AES_CBC 加密和解密给定文本。我想知道为什么当plaintextciphertextchecktext 不是全局变量并且它们是全局变量时我会在标题中出现错误。谢谢!

#include <stdio.h>
#include <openssl\aes.h>
#include <openssl\rand.h>
#include <conio.h>
#include <openssl\des.h>

#define BIG_TEST_SIZE 1024

char plaintext[BIG_TEST_SIZE];
char ciphertext[BIG_TEST_SIZE];
char checktext[BIG_TEST_SIZE];

AES_KEY key;
char rkey[32+1];

static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
{
        int n=0;

        fprintf(f,"%s",title);
        for( ; n < l ; ++n)
        {
                if((n%16) == 0)
                        fprintf(f,"\n%04x",n);
                fprintf(f," %02x",s[n]);
        }
        fprintf(f,"\n");
}

int main(int argc, char* argv[])
{
    //char plaintext[BIG_TEST_SIZE];
    //char ciphertext[BIG_TEST_SIZE];
    //char checktext[BIG_TEST_SIZE];    

    char saved_iv[32+1];
        int err = 0;

        RAND_pseudo_bytes((unsigned char*)rkey, sizeof rkey);
        unsigned char iv[32+1]="01234567890123456789012345678901";

        memcpy(saved_iv, iv, sizeof saved_iv);

        strcpy((char*)plaintext,"aaa");

        const size_t encslength = ((strlen(plaintext) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
        // Straight encrypt

        AES_set_encrypt_key((unsigned char*)rkey, 256, &key);
        hexdump(stdout, "plaintext", (unsigned char*)plaintext, strlen(plaintext));

        AES_cbc_encrypt((unsigned char*)plaintext, (unsigned char*)ciphertext, encslength, &key, (unsigned char*)iv,AES_ENCRYPT);
        hexdump(stdout, "ciphertext", (unsigned char*)ciphertext, strlen(plaintext));

        // Straight decrypt

        AES_set_decrypt_key((unsigned char*)rkey, 256, &key);
        memcpy(iv, saved_iv, sizeof iv);

        AES_cbc_encrypt((unsigned char*)ciphertext, (unsigned char*)checktext, encslength, &key, (unsigned char*)iv,AES_DECRYPT);
        hexdump(stdout, "checktext", (unsigned char*)checktext, strlen(plaintext));


        getch();
}

【问题讨论】:

  • 因为它们在main 中声明时是在堆栈上分配的。您可以使用诸如 valgrind 之类的工具来查找无效的写入和读取。
  • plaintext[] 是一个数组,所以 strcpy( plaintext, "aaa");是正确的。实际使用的代码将明文的第一个(指针大小)字节视为指向“aaa”存储位置的指针。除了这个错误,代码中还有其他类似的错误。

标签: c++ c openssl aes stack-corruption


【解决方案1】:

全局变量和静态变量初始化为零,而局部变量则不是。 因此,当您在本地定义 plaintextciphertextchecktext 时,使用 memset 将它们初始化为零。 您的字符串应该以空值结尾,但在您的情况下不是。 ciphertextchecktext 不是以 null 结尾的。而 plaintext 由于 strcpy 调用而变为空终止。

【讨论】:

  • 我不认为这是正确的。 strcpy:“将源指向的 C 字符串复制到目标指向的数组中,包括终止的空字符(并在该点停止)。” cplusplus.com/reference/cstring/strcpy 的示例正在做完全相同的事情(第 11 行)。
  • 我认为一定有一些带有空终止字符的东西(我使用了一个 3 长度的字符串作为输入,并且在达到最大限制之前输出不会结束),但我不知道为什么。
猜你喜欢
  • 2018-03-12
  • 1970-01-01
  • 2021-03-28
  • 2012-11-08
  • 2019-09-04
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多