OpenSSL是否具有GMAC API和示例

时间:2014-09-23 19:58:31

标签: authentication openssl aes-gcm

我正在开发一个需要对大量数据进行身份验证的项目。似乎GMAC专为高吞吐量操作而设计。我只需要消息验证码,不需要加密。 OpenSSL是否具有GMAC API或仅计算GMAC代码的示例?

我知道GCM用于加密和身份验证,但对于我的情况,不需要加密。有没有使用openssl进行GMAC计算的例子?

1 个答案:

答案 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