2

gcrypt を使用して単純な暗号化を txt ファイルにしようとしています。コマンドを実行するとgcry_cipher_encrypt、次のエラーが表示されます。

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

これは、1 つの 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 を追加すると) txtLength64 であり、正確に 16 の倍数になります。

テキストは 25 バイトなので、texLength26 の場合は 16 の倍数ではありません。

パッサン: あなたは C++ を使用しているため、使用を避けて代わりにmalloc()使用することを強くお勧めします。new []または(より良い、IMHO)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 に答える