6

我正在使用 libgcrypt(Gentoo x64 上的 v1.6.1)并且我已经实现(并通过 AE 测试向量进行了测试)aes256-cbc 和 aes256-ctr。现在我正在查看 aes256-gcm 但我对工作流程有些怀疑。下面是一个简单的加密程序的骨架:

int main(void){

    unsigned char TEST_KEY[] = {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4};
    unsigned char TEST_IV[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
    unsigned char TEST_PLAINTEXT_1[] = {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a};

    unsigned char cipher[16] = {0};

    int algo = -1, i;
    const char *name = "aes256";

    algo = gcry_cipher_map_name(name);

    gcry_cipher_hd_t hd;
    gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_GCM, 0);
    gcry_cipher_setkey(hd, TEST_KEY, 32);
    gcry_cipher_setiv(hd, TEST_IV, 16);

    gcry_cipher_encrypt(hd, cipher, 16, TEST_PLAINTEXT_1, 16);
    char out[33];
    for(i=0;i<16;i++){
        sprintf(out+(i*2), "%02x", cipher[i]);
    }
    out[32] = '\0';
    printf("%s\n", out);

    gcry_cipher_close(hd);

    return 0;
}

在 GCM 模式下,还需要这些指令:

gcry_cipher_authenticate (gcry cipher hd t h , const void * abuf , size t abuflen )
gcry_error_t gcry_cipher_gettag (gcry cipher hd t h , void * tag , size t taglen )

所以加密程序的正确工作流程是:

gcry_cipher_authenticate
gcry_cipher_encrypt
gcry_cipher_gettag

但我没有明白的是:

  1. abuf就像盐一样?(所以我必须使用gcry_create_nonce或类似方法生成它吗?)
  2. 如果我想加密一个文件,void *tag我必须写入输出文件吗?
4

1 回答 1

5

1) gcry_cipher_authenticate 用于支持带有关联数据的经过身份验证的加密。abuf 是您需要验证但不需要加密的数据。例如,如果您要发送一个数据包,您可能想要加密正文,但您必须发送未加密的标头才能传递数据包。密码生成的标签将为加密数据和明文发送的数据提供完整性。

2) 解密后使用标签,确保数据未被篡改。您将标记附加到加密文本。请注意,它是根据加密数据和相关(未加密)数据计算的,因此在解密时您将需要两者。

您可以查看这些文档以获取有关 GCM 的更多信息:

http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800 -38D.pdf

此外,您可能可以在http://crypto.stackexchange.com上获得更快的密码学问题答案。

于 2014-02-21T07:08:36.323 回答