HMAC与CMAC

Posted 嵌入式软件实战派

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HMAC与CMAC相关的知识,希望对你有一定的参考价值。

在信息科技蓬勃发展的今天,万物互联概念的出现,这使得信息安全的要求越来越重要,需求也越来越迫切。其中,消息验证(MAC)是信息安全中重要一笔。在嵌入式领域,HMAC和CMAC使用的特别广泛。

那么,MAC是什么?HMAC和CMAC又是什么,他们各有什么特点和什么区别呢?

MAC

在密码学中,消息验证码 (MAC,Message Authentication Code),有时也称为标签(Tag),是用于验证消息的一小段信息。换句话说,用于确认消息来自指定的发送者(其真实性)并且没有被篡改了。

一般情况下,消息认证码由三种算法组成:

  1. 密钥生成算法从密钥空间中随机均匀地选择一个密钥。
  2. 签名算法有效地返回给定密钥和消息的标签。
  3. 验证算法有效地验证给定密钥和标签的消息的真实性。 也就是说,当消息和标签没有被篡改或伪造时,返回被接受,否则返回被拒绝。

在这里插入图片描述

MAC算法可以由其他密码原语构造,如密码散列函数(如HMAC的情况)或分组密码算法(OMAC、CBC-MAC和PMAC)。 然而,许多最快的MAC算法(如 UMAC 和 VMAC)都是基于通用哈希构建的。
此外,MAC 算法可以故意组合两个或多个密码原语,以保持保护,即使后来发现其中之一易受攻击。 例如,在传输层安全 (TLS) 中,输入数据被分成两半,每半都用不同的散列原语(MD5 和 SHA-1)处理,然后一起异或以输出 MAC。

HMAC

HMAC即keyed-Hash Message Authentication Code或者Hash-based Message Authentication Code的缩写,它是一种特定类型的消息验证码 (MAC),涉及加密散列函数和秘密加密密钥。

很明显,HMAC中的H,指的就是Hash或者Hash Function。

任何加密散列函数(Hash Function),例如 SHA-2 或 SHA-3,都可以用于计算 HMAC;生成的 MAC 算法称为 HMAC-X,其中 X 是使用的哈希函数(例如 HMAC-SHA256 或 HMAC-SHA3-256)。 HMAC 的加密强度取决于底层散列函数的加密强度、其散列输出的大小以及密钥的大小和质量。

HMAC 使用两遍散列计算。秘密密钥首先用于派生两个密钥——内部密钥和外部密钥。该算法的第一遍产生从消息和内部密钥派生的内部散列。第二遍生成从内部散列结果和外部密钥派生的最终 HMAC 代码。因此,该算法对长度扩展攻击提供了更好的免疫力。

要使用 HMAC 函数计算数据“text”上的 MAC,执行以下操作:

MAC(text) = HMAC(K, text) = H((K0 ⊕ opad )|| H((K0 ⊕ ipad) || text))
下面通过表格和图示阐述这个算法过程:

在这里插入图片描述
在这里插入图片描述

HMAC怎么实现的?下面是一段伪代码:


function hmac is
    input:
        key:        Bytes    // Array of bytes
        message:    Bytes    // Array of bytes to be hashed
        hash:       Function // The hash function to use (e.g. SHA-1)
        blockSize:  Integer  // The block size of the hash function (e.g. 64 bytes for SHA-1)
        outputSize: Integer  // The output size of the hash function (e.g. 20 bytes for SHA-1)
 
    // Keys longer than blockSize are shortened by hashing them
    if (length(key) > blockSize) then
        h ← hash(key) // h is outputSize bytes long
        while (length(h) < blockSize) do
            h ← h ∥ hash(h ∥ key)  // Where ∥ is concatenation
        key ← Truncate(h, blockSize) // reduce length to blockSize    // Keys shorter than blockSize are padded to blockSize by padding with zeros on the right
    if (length(key) < blockSize) then
        key ← Pad(key, blockSize) // Pad key with zeros to make it blockSize bytes long    o_key_pad ← key xor [0x5c * blockSize]   // Outer padded key
    i_key_pad ← key xor [0x36 * blockSize]   // Inner padded key    return hash(o_key_pad ∥ hash(i_key_pad ∥ message))

CMAC

CMAC是Cipher-based Message Authentication Code的缩写,它是一种基于分组密码的消息认证码算法。

但是,如果你搜索CMAC,在wikipedia上是找不到专门词条的,它会被重定向到One-Key MAC。

难道CMAC就是OMAC?

先了解下这个One-Key MAC (OMAC) 。

One-Key MAC (OMAC) 是一种消息验证代码,由类似于 CBC-MAC 算法的分组密码构造而成。
官方有两种 OMAC 算法(OMAC1 和 OMAC2),除了小幅调整外,它们基本上相同。 OMAC1 相当于 CMAC,后者于 2005 年 5 月成为 NIST 推荐标准。

所以,CMAC是相当于OMAC1。

CMAC是对所有用途都是免费的:它不受任何专利保护。 在密码学中,它是一种基于分组密码的消息认证码算法。它可用于提供真实性的保证,从而保证二进制数据的完整性。这种操作模式修复了 CBC-MAC 的安全缺陷(CBC-MAC 仅对固定长度的消息是安全的)。

另外,CMAC 算法的核心是 Black 和 Rogaway 以 XCBC 的名义提出和分析并提交给 NIST的 CBC-MAC 的变体。 XCBC 算法有效地解决了 CBC-MAC 的安全缺陷,但需要三个密钥。 Iwata 和 Kurosawa 提出了 XCBC 的改进,并在他们的论文中将所得算法命名为 One-Key CBC-MAC (OMAC)。 他们后来提交了 OMAC1、OMAC 的改进和额外的安全分析。 OMAC 算法减少了 XCBC 所需的密钥材料量。

在这里插入图片描述

要使用b位分组密码(E)和密钥(k)生成消息(m)的ℓ位CMAC标记 (t),首先要生成2个b位子密钥(k1和k2)使用以下算法(这相当于在有限域 GF(2^b) 中乘以 x 和 x2)。 让 ≪ 表示标准的左移运算符,⊕ 表示按位互斥,或者:

  1. 计算一个临时变量值 k0 = Ek(0).
  2. 如果msb(k0) = 0, 那么k1 = k0 ≪ 1, 否则k1 = (k0 ≪ 1) ⊕ C; 这里C 是某个常数,仅取决于 b。(具体来说,C 是字典序第一个不可约 b 次二元多项式的非前导系数,其中 1 的个数最少:0x1B 表示 64 位,0x87 表示 128 位,0x425 表示 256 位块。)
  3. 如果msb(k1) = 0,那么k2 = k1 ≪ 1,否则k2 = (k1 ≪ 1) ⊕ C。
  4. 返回 MAC 生成过程的密钥 (k1, k2)。

作为一个小案例,假设b = 4,C = 00112,k0 = Ek(0) = 01012。那么k1 = 10102和k2 = 0100 ⊕ 0011 = 01112。

CMAC tag的生成流程如下:

  1. 将消息分成 b 位块 m = m1 ∥ … ∥ mn−1 ∥ mn,其中 m1, …, mn−1 是完整块。 (空消息被视为一个不完整的块。)
  2. 如果 mn 是一个完整的块,则 mn′ = k1 ⊕ mn 否则 mn′ = k2 ⊕ (mn ∥ 10…02)。
  3. 使c0 = 00…02.
  4. 对于i = 1, …, n − 1,计算ci = Ek(ci−1 ⊕ mi).
  5. cn = Ek(cn−1 ⊕ mn′)
  6. 输出t = msbℓ(cn).

验证过程如下:

  1. 使用上述算法生成标签。
  2. 检查生成的标签是否与接收的标签相同。

HMAC与CMAC

综上,对比HMAC和CMAC异同。

HMAC是基于Hash的MAC,而CMAC是基于分组密码的MAC,可以简单理解为他们都是MAC,都是做消息认证用的,只是他们的实现方式不一样。

因为HMAC是基于Hash的,计算起来会快一点。其实在嵌入式领域,HMAC和CMAC都可以使用,另外CMAC在嵌入式使用上是非常多的。

实际上,对于MAC,除了HMAC和CMAC,其实还有VMAC、NMAC、PMAC……在此就不一一详述了。

下期预告:HMAC和CMAC是怎么实现的,有没有C/C++或者Python的案例源码?

关注“嵌入式软件实战派”,获得更多精彩内容。

在这里插入图片描述

以上是关于HMAC与CMAC的主要内容,如果未能解决你的问题,请参考以下文章

如何在matlab中使用base64输出重现相同的python hmac

如何使用 OpenSSL 的 CMAC_xxx 函数计算 AES CMAC?

CMAC小脑CMAC逼近sin(t)函数的训练和测试

CMAC基于CMAC小脑模型的人体行走姿态识别算法仿真

python实现HMAC算法与应用

DAA和CMAC