c++ - 在函数 gcry_cipher_encrypt C++ 上使用 gcrypt 时出错

标签 c++ linux libgcrypt

我正在尝试使用 gcrypt 将简单的密码学制作为 txt 文件。当我执行命令 gcry_cipher_encrypt 时,我收到以下错误:

gcry_strsource => User defined source 1
gcry_strerror => Invalid length

当我使用一个txt文件的内容时,会发生这种情况,如果我在该函数起作用的代码中硬编码文本内容,可能的原因是什么?

文本文件内容

test test test test test 

密码:

void myEncrypt::aesEncrypt(char *txtInput, int txtInputSize, char *txtOutput){

    gcry_error_t     gcryError;
    gcry_cipher_hd_t gcryCipherHd;
    size_t           index;


    size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
    size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
    //char * txtBuffer = "123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ";
    char * txtBuffer = txtInput;
    size_t txtLength = strlen(txtBuffer)+1; // string plus termination
    char * encBuffer = (char *)malloc(txtLength);
    char * outBuffer = (char *)malloc(txtLength);
    char * aesSymKey = "one test AES key"; // 16 bytes
    char * iniVector = "a test ini value"; // 16 bytes

    gcryError = gcry_cipher_open(
        &gcryCipherHd, // gcry_cipher_hd_t *
        GCRY_CIPHER,   // int
        GCRY_C_MODE,   // int
        0);            // unsigned int
    if (gcryError)
    {
        printf("gcry_cipher_open failed:  %s/%s\n",
               gcry_strsource(gcryError),
               gcry_strerror(gcryError));
        return;
    }
    printf("gcry_cipher_open    worked\n");

    gcryError = gcry_cipher_setkey(gcryCipherHd, aesSymKey, keyLength);
    if (gcryError)
    {
        printf("gcry_cipher_setkey failed:  %s/%s\n",
               gcry_strsource(gcryError),
               gcry_strerror(gcryError));
        return;
    }
    printf("gcry_cipher_setkey  worked\n");

    gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
    if (gcryError)
    {
        printf("gcry_cipher_setiv failed:  %s/%s\n",
               gcry_strsource(gcryError),
               gcry_strerror(gcryError));
        return;
    }
    printf("gcry_cipher_setiv   worked\n");

    gcryError = gcry_cipher_encrypt(
        gcryCipherHd, // gcry_cipher_hd_t
        encBuffer,    // void *
        txtLength,    // size_t
        txtBuffer,    // const void *
        txtLength);   // size_t
    if (gcryError)
    {
        printf("gcry_cipher_encrypt failed:  %s/%s\n",
               gcry_strsource(gcryError),
               gcry_strerror(gcryError));
        return;
    }
    printf("gcry_cipher_encrypt worked\n");

    gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
    if (gcryError)
    {
        printf("gcry_cipher_setiv failed:  %s/%s\n",
               gcry_strsource(gcryError),
               gcry_strerror(gcryError));
        return;
    }
    printf("gcry_cipher_setiv   worked\n");

    gcryError = gcry_cipher_decrypt(
        gcryCipherHd, // gcry_cipher_hd_t
        outBuffer,    // void *
        txtLength,    // size_t
        encBuffer,    // const void *
        txtLength);   // size_t
    if (gcryError)
    {
        printf("gcry_cipher_decrypt failed:  %s/%s\n",
               gcry_strsource(gcryError),
               gcry_strerror(gcryError));
        return;
    }
    printf("gcry_cipher_decrypt worked\n");

    printf("keyLength = %d\n", keyLength);
    printf("blkLength = %d\n", blkLength);
    printf("txtLength = %d\n", txtLength);
    printf("aesSymKey = %s\n", aesSymKey);
    printf("iniVector = %s\n", iniVector);
    printf("txtBuffer = %s\n", txtBuffer);

    printf("encBuffer = ");
    for (index = 0; index<txtLength; index++)
        printf("%02X", (unsigned char)encBuffer[index]);
    printf("\n");

    printf("outBuffer = %s\n", outBuffer);

    // clean up after ourselves
    gcry_cipher_close(gcryCipherHd);
    free(encBuffer);
    free(outBuffer);
}

最佳答案

嗯...我不知道 libgcrypt,但是...

this page ,在gcry_cipher_encrypt()函数的描述中,我读到了

Depending on the selected algorithms and encryption mode, the length of the buffers must be a multiple of the block size.

如果我理解得很好,您正在使用 AES 作为算法,因此根据各种来源(例如 wikipedia ),AES 的 block 大小为 16 字节。

如果您查看原始的 txtBuffer,您会发现它有 63 个字节(9 个数字、26+26 个字母、2 个空格),因此(为终端零添加 +1)txtLength 是 64,正好是 16 的倍数。

您的文本有 25 个字节,因此您的 texLength 如果是 26,则不是 16 的倍数。

顺便说一句:您使用的是 C++,因此我强烈建议避免使用 malloc() 并使用 new [] ;或(更好,恕我直言)std::stringreserve()c_str()data() .

我想你应该使用txtBuffer作为中间分配的缓冲区。

使用new []解决方案,我想你应该以这种方式修改你的代码

std::size_t txtLength = strlen(txtInput)+1; // from txtInput, not txtBuffer

if ( 0U != (txtLength & 0xfU) )
   txtLength += 0x10U - (txtLength & 0xfU);

char * txtBuffer = new char[txtLength];
char * encBuffer = new char[txtLength];
char * outBuffer = new char[txtLength];

std::strcpy(txtBuffer, txtInput);

附注:小心,代码未经测试。

p.s.2:抱歉我的英语不好。

关于c++ - 在函数 gcry_cipher_encrypt C++ 上使用 gcrypt 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37490864/

相关文章:

c++ - 将dat文件转换为数字

linux - 为什么在停止 Apache 服务后,我的 IP 地址仍然可以看到 Apache 默认页面?

c 编程 - 来自 DIR* 结构的目录名

c - 使用 libgcrypt 和 Elgamal 加密和解密时数据丢失

visual-c++ - libgcrypt.lib中无法解析的外部符号

c++ - cbegin()/cend() 与 constBegin()/constEnd()

c++ - 从/向文件读写 double

c++ - FLTK 1.4 小部件位置 w.r.t. X11 根窗口?

c - 使用 libgcrypt 从密码加密文件

c++ - 在 C++ 中用于用户输入的二维数组