2

我正在尝试使用 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);
}
4

1 回答 1

2

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

此页面中,在gcry_cipher_encrypt()功能描述中,我阅读了

根据所选算法和加密模式,缓冲区的长度必须是块大小的倍数。

如果我理解得很好,那么您使用的是 AES 作为算法,因此,根据各种来源(例如维基百科),AES 的块大小为 16 个字节。

如果你看一下原来的txtBuffer,你可以看到它有 63 个字节(9 个数字,26+26 个字母,2 个空格),所以(为终端零添加 +1)txtLength是 64,正好是 16 的倍数。

你的文本有 25 个字节,所以你的texLengthif 26 不是 16 的倍数。

顺便说一句:你正在使用 C++,所以我强烈建议避免使用 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);

ps:谨慎,代码未经测试。

ps2:对不起我的英语不好。

于 2016-05-28T12:54:11.357 回答