C中的Libgcrypt返回42

C中的Libgcrypt返回42,c,encryption,aes,libgcrypt,C,Encryption,Aes,Libgcrypt,我想先介绍一下,我是C语言的新手,尤其是使用像libgcrypt这样大的库,所以如果它非常简单,请理解 所以,我一直在尝试对一些文本进行加密,这样我就可以在加密字节之前获得更好的信心,这是这个小应用程序的最终目标之一,如果你愿意这么说的话。我一直在关注,但仍在努力让它发挥作用。真正让我困惑的是,我正在将大小与in-text匹配的out缓冲区传递给它。我确实觉得奇怪,这个网站告诉我使输出缓冲区与输入缓冲区的大小相同,即使通常使用AES加密时,输出的字节数很大。也许我错过了一些更有经验的人可以帮助我

我想先介绍一下,我是C语言的新手,尤其是使用像libgcrypt这样大的库,所以如果它非常简单,请理解


所以,我一直在尝试对一些文本进行加密,这样我就可以在加密字节之前获得更好的信心,这是这个小应用程序的最终目标之一,如果你愿意这么说的话。我一直在关注,但仍在努力让它发挥作用。真正让我困惑的是,我正在将大小与in-text匹配的out缓冲区传递给它。我确实觉得奇怪,这个网站告诉我使输出缓冲区与输入缓冲区的大小相同,即使通常使用AES加密时,输出的字节数很大。也许我错过了一些更有经验的人可以帮助我的东西,我已经阅读了他们的代码至少3-4次了,我觉得这一定是我在这里错过的超级简单的东西

编辑 客户端.c

#include "client.h"

void printGCRYPTError(gcry_error_t err) {
    if (err) {
         {
           fprintf (stderr, "Failure: %s/%s\n",
                    gcry_strsource (err),
                    gcry_strerror (err));
           fprintf (stdout, "Failure: %s/%s\n",
                    gcry_strsource (err),
                    gcry_strerror (err));
         }
    }
}

char* Encrypt(char* in, char* key, char* iv){
    size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
    size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);

    if(strlen(key) != keyLength) {
        printf("Invalid Key Size. Expected %zu got %lu\n", keyLength, strlen(key));
        return NULL;
    }
    if(strlen(iv) != blkLength) {
        printf("Invalid BLK/IV Size. Expected %zu got %lu\n", blkLength, strlen(iv));
        return NULL;
    }

    gcry_cipher_hd_t handle;
    gcry_error_t err = 0;

    size_t inLen = strlen(in)+1;
    char * out = malloc(inLen);

    // Open
    err = gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_C_MODE, 0);
    printGCRYPTError(err);

    // Set Key
    err = gcry_cipher_setkey(handle, key, keyLength);
    printGCRYPTError(err);

    // Set IV
    err = gcry_cipher_setiv(handle, iv, blkLength);
    printGCRYPTError(err);

    // Enc
    printf("Encrypting...\n");
    err = gcry_cipher_encrypt(handle, out, inLen, in, inLen);
    printGCRYPTError(err);
    printf("Encrypted.\n");
    gcry_cipher_final(handle);


    //Out
    printf("Plaintext Message: %s\n", in);
    printf("Encrypted Message: ");
    int index = 0;
    for (index = 0; index<inLen; index++) {
        printf("%02X", (unsigned char)out[index]);
    }
    printf("\n");

    // Cleanup!
    gcry_cipher_close(handle);

    // Return
    return out;
}

char* Decrypt(char* in, char* key, char* iv){
    size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
    size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);

    if(strlen(key) != keyLength) {
        printf("Invalid Key Size. Expected %zu got %lu\n", keyLength, strlen(key));
        return NULL;
    }
    if(strlen(iv) != blkLength) {
        printf("Invalid BLK/IV Size. Expected %zu got %lu\n", blkLength, strlen(iv));
        return NULL;
    }

    gcry_cipher_hd_t handle;
    gcry_error_t err = 0;

    size_t inLen = strlen(in);
    char * out = malloc(inLen);

    // Open
    err = gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_C_MODE, 0);
    printGCRYPTError(err);

    // Set Key
    err = gcry_cipher_setkey(handle, key, keyLength);
    printGCRYPTError(err);

    // Set IV
    err = gcry_cipher_setiv(handle, iv, blkLength);
    printGCRYPTError(err);

    // Dec
    printf("Decrypting...\n");
    err = gcry_cipher_decrypt(handle, out, inLen, in, inLen);
    printGCRYPTError(err);
    printf("Decrypted.\n");
    gcry_cipher_final(handle);

    //Out
    printf("Encrypted Message: ");
    int index = 0;
    for (index = 0; index<inLen; index++) {
        printf("%02X", (unsigned char)out[index]);
    }
    printf("\n");
    printf("Decrypted Message: %s\n", out);

    // Cleanup!
    gcry_cipher_close(handle);

    // Return
    return out;
}

int main() {
    //aesTest();
    char* encrypted = Encrypt("My test message", "sBK0hcXddz6mIKEsBK0hcXddz6mIKEAS", "sBK0uhSAUSUSHKES");
    char* decrypted = Decrypt(encrypted, "sBK0hcXddz6mIKEsBK0hcXddz6mIKEAS", "sBK0uhSAUSUSHKES");
}
谢谢你的关注

根据以下文件:

某些加密模式要求在加密之前使用gcry\u cipher\u final 最后一个数据块被传递到此函数

所以我想你需要做两件事:

  • 检查来自
    gcry\u cipher\u encrypt
    的错误代码结果,该结果与您之前执行函数调用的方式一致

  • 调用encrypt后调用
    gcry\u cipher\u final(handle)
    ——假设您正在对小于密码块长度的缓冲区进行一次性加密

  • 正如所建议的,检查
    gcry\u cipher\u encrypt
    返回的错误非常有用:它显示“Failure:gcrypt/Invalid length”

    根本原因似乎是
    inLen

    size\u t inLen=strlen(英寸);
    ...
    err=gcry\u cipher\u encrypt(句柄、out、inLen、in、inLen);
    印刷镜(err);
    gcry_密码_最终(句柄);
    
    返回(预期?)输出


    除了密钥问题,我需要在加密之前将填充添加到AES明文中。

    没有更改,这是奇怪的部分,我在执行时没有收到任何错误。我欠你一个道歉,我以为我让它在加密后打印错误。我的错。我以为我让它在加密后打印错误。是我的错。我也会测试一下。我需要填充。另一个小问题是,如果我只给你加密的文本,你能在没有明文长度的情况下解密它吗?就像我希望能够在不发送明文大小的情况下传输数据一样,“虽然通常使用AES加密时,输出的字节数很大”。。。通常定义。AES的许多模式都是流式操作模式。你只会在CBC/ECB/PCBC中获得此信息,而不会窃取cihpertext。如果希望密文大小与输入大小匹配(以位/字节为单位),请使用计数器模式。我没有看到任何计算输出密码文本的函数,大概
    gcrypt
    认为计算和填充是您的责任。如果是这样的话,那就是一些低级加密库。相比之下,OpenSSL
    EVP
    函数将被认为是高级别的。下次请不要遗漏类似于
    GCRY\u CIPHER
    、发生错误的地方等内容。这并不是答案的原因,我确实声明了这是AES,所以填充与GCRY\u密码无关仍然是一个很好的地方。
    Encrypting...
    Encrypted.
    Plaintext Message: My test message
    Encrypted Message: 153C01DD7821E5113C25D2038F3644F7
    Decrypting...
    Failure: gcrypt/Invalid length
    Failure: gcrypt/Invalid length
    Decrypted.
    Encrypted Message: 0000000000001000000000000000101400
    Decrypted Message: 
    
    Message: My test message!
    Encrypted Message = AEDBBB645CA54F16B5A279D77772A97B