我正在开发一个需要对大量数据进行身份验证的项目。似乎GMAC专为高吞吐量操作而设计。我只需要消息验证码,不需要加密。 OpenSSL是否具有GMAC API或仅计算GMAC代码的示例?
我知道GCM用于加密和身份验证,但对于我的情况,不需要加密。有没有使用openssl进行GMAC计算的例子?
答案 0 :(得分:4)
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