我正在做一个需要对大量数据进行身份验证的项目。似乎 GMAC 是为高吞吐量操作而设计的。我只需要消息验证码,不需要加密。OpenSSL 是否具有仅计算 GMAC 代码的 GMAC API 或示例?
我知道 GCM 用于加密和身份验证,但对于我的情况,不需要加密。有没有仅使用 openssl 进行 GMAC 计算的示例?
我正在做一个需要对大量数据进行身份验证的项目。似乎 GMAC 是为高吞吐量操作而设计的。我只需要消息验证码,不需要加密。OpenSSL 是否具有仅计算 GMAC 代码的 GMAC API 或示例?
我知道 GCM 用于加密和身份验证,但对于我的情况,不需要加密。有没有仅使用 openssl 进行 GMAC 计算的示例?
OpenSSL 是否有 GMAC API 和示例...
OpenSSL wiki 在EVP Authenticated Encryption and Decryption上有一个 Authenticated Encryption 模式示例。
GMAC 是 GCM 模式的一个特例。来自 NIST 的特别出版物 800-38D:
如果 GCM 输入仅限于不加密的数据,则由此产生的 GCM 专业化,称为 GMAC,只是输入数据的一种身份验证模式......
因此,您需要做的就是将数据发送到附加认证数据 (AAD) 通道,而不是纯文本 (PT) 通道。
这是一个使用 NIST 的GCM 测试向量中的测试向量的示例。请注意,PT 数据为空,仅提供 AAD 数据:
[Keylen = 128]
[IVlen = 96]
[PTlen = 0]
[AADlen = 128]
[Taglen = 128]
Count = 0
Key = 77be63708971c4e240d1cb79e8d77feb
IV = e0e00f19fed7ba0136a797f3
PT =
AAD = 7a43ec1d9c0a5a78a0b16533a6213cab
CT =
Tag = 209fcc8d3675ed938e9c7166709dd946
这是使用硬编码数据的程序(以及在OpenSSL GMAC 示例的 Pastebin 上):
int rc = 0, unused;
unsigned int i;
byte key[] = { 0x77, 0xbe, 0x63, 0x70, 0x89, 0x71, 0xc4, 0xe2,
0x40, 0xd1, 0xcb, 0x79, 0xe8, 0xd7, 0x7f, 0xeb };
byte iv[] = { 0xe0, 0xe0, 0x0f, 0x19, 0xfe, 0xd7, 0xba, 0x01,
0x36, 0xa7, 0x97, 0xf3 };
byte aad[] = { 0x7a, 0x43, 0xec, 0x1d, 0x9c, 0x0a, 0x5a, 0x78,
0xa0, 0xb1, 0x65, 0x33, 0xa6, 0x21, 0x3c, 0xab };
byte tag[16] = { /* calculated */ };
byte exp[] = { 0x20, 0x9f, 0xcc, 0x8d, 0x36, 0x75, 0xed, 0x93,
0x8e, 0x9c, 0x71, 0x66, 0x70, 0x9d, 0xd9, 0x46 };
EVP_CIPHER_CTX *ctx = NULL;
ctx = EVP_CIPHER_CTX_new();
ASSERT(ctx != NULL);
rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
ASSERT(rc == 1);
rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL);
ASSERT(rc == 1);
rc = EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv);
ASSERT(rc == 1);
rc = EVP_EncryptUpdate(ctx, NULL, &unused, aad, sizeof(aad));
ASSERT(rc == 1);
rc = EVP_EncryptFinal_ex(ctx, NULL, &unused);
ASSERT(rc == 1);
rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag);
ASSERT(rc == 1);
printf("Calculated tag:\n ");
for(i = 0; i < sizeof(tag); i++)
{
printf("%02x", tag[i]);
if(i == sizeof(tag) - 1) {
printf("\n");
}
}
printf("Expected tag:\n ");
for(i = 0; i < sizeof(exp); i++)
{
printf("%02x", exp[i]);
if(i == sizeof(exp) - 1) {
printf("\n");
}
}
if(ctx) {
EVP_CIPHER_CTX_free(ctx);
}
最后,这是程序的输出:
$ ./t.exe
Calculated tag:
209fcc8d3675ed938e9c7166709dd946
Expected tag:
209fcc8d3675ed938e9c7166709dd946