我正在做一个需要对大量数据进行身份验证的项目。看来GMAC是为高吞吐量操作而设计的。我只需要消息验证码,不需要加密。
OpenSSL是否具有GMAC API或仅计算GMAC代码的示例?
我知道GCM用于加密和身份验证,但就我而言,不需要加密。是否有仅使用openssl进行GMAC计算的示例?
最佳答案
OpenSSL是否具有GMAC API和示例...
OpenSSL Wiki在EVP Authenticated Encryption and Decryption处具有“身份验证加密”模式示例。
GMAC是GCM模式的特例。来自NIST的Special Publication 800-38D:
如果GCM输入仅限于不加密的数据,
由此产生的GCM专业化称为GMAC,
输入数据上的身份验证模式...
因此,您要做的就是将数据发送到“其他身份验证数据(AAD)”通道,而不是纯文本(PT)通道。
这是一个使用NIST GCM Test Vectors中的测试向量的示例。请注意,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 example的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