17、密钥哈希:构建安全消息认证码的多种方法

密钥哈希构建安全消息认证码的方法

密钥哈希:构建安全消息认证码的多种方法

1. 密钥前缀构造的安全隐患

密钥前缀构造(secret - prefix construction)在哈希函数中存在一定的安全问题。
- 长度扩展攻击的威胁 :SHA - 2 系列的哈希函数容易受到长度扩展攻击。攻击者在已知较短消息的哈希值 Hash(K || M1) 时,无需知道 M1 和密钥 K ,就能计算出 Hash(K || M1 || M2) 。这使得攻击者可以免费伪造有效的 MAC 标签,因为他们原本不应仅根据 M1 的 MAC 猜出 M1 || M2 的 MAC。Merkle - Damgård 结构存在允许长度扩展攻击的弱点,而 SHA - 3 的候选者都具备抵御此类攻击的能力。
- 不同密钥长度的风险 :当允许使用不同长度的密钥时,密钥前缀构造也不安全。例如,不同长度的密钥 K 与消息 M 组合后,可能会得到相同的 K || M 值,从而导致哈希结果相同。虽然可以通过对密钥长度、密钥和消息一起哈希(如 Hash(L || K || M) ,其中 L 是密钥长度的 16 位整数编码)来解决,但现代哈希函数如 BLAKE2 和 SHA - 3 包含密钥模式,可避免这些问题,提供安全的 PRF 和 MAC。

2. 密钥后缀构造
# 多项式滚动哈希详解 ## 什么是多项式滚动哈希? 多项式滚动哈希是一种将字符串映射为整数的技术,用于快速比较两个字符串是否相等。其核心思想是把字符串看作一个**多位数**,每一位是一个字符,基数(进制)通常取 31 或 131。 数学表达式如下: $$ H(s) = \sum_{i=0}^{n-1} (s[i] - 'a' + 1) \cdot \text{base}^{n-1-i} $$ 其中: - $ s[i] $ 是字符串第 $i$ 个字符 - `base` 是选定的进制数(常用 31) - $ H(s) $ 是该字符串的哈希值 --- ## 如何理解? 想象我们有一个数字 "1234",它的值是: $$ 1 \times 10^3 + 2 \times 10^2 + 3 \times 10^1 + 4 \times 10^0 $$ 多项式哈希类似,只不过: - 每一位不是 0~9,而是 'a'~'z' - 把 'a' 映射为 1,'b'→2,…,'z'→26(避免 0 引起冲突) - 进制不再是 10,而是 31(或其他质数) 例如:字符串 `"abc"` 的哈希值为: $$ H("abc") = (1)\cdot31^2 + (2)\cdot31^1 + (3)\cdot31^0 = 961 + 62 + 3 = 1026 $$ --- ## 为什么要用 31? - 31 是一个较小的质数,分布良好 - 编译器会将其优化为位运算:`31 * x == (x << 5) - x` - 经验表明,在大多数情况下能有效减少哈希冲突 --- ## 实现代码(C/C++) ```c long long poly_hash(char s[], int len) { long long hash_val = 0; long long base = 31; for (int i = 0; i < len; i++) { hash_val = hash_val * base + (s[i] - 'a' + 1); // 避免'a'=0 } return hash_val; } ``` ### 示例演示: | 字符串 | 哈希计算过程 | |--------|-------------| | `"ab"` | $ 1\cdot31 + 2 = 33 $ | | `"ba"` | $ 2\cdot31 + 1 = 63 $ | | `"aa"` | $ 1\cdot31 + 1 = 32 $ | 可以看到不同顺序的字符串哈希值不同,具有良好的区分性。 --- ## 注意事项与局限 ### ✅ 优点: - 时间复杂度低:$O(n)$ 构造,$O(1)$ 比较 - 空间节省:只需存储一个 `long long` 值 - 支持滚动更新(可用于 Rabin-Karp 算法) ### ❌ 缺点: - 存在哈希冲突风险(不同字符串可能同哈希) - 单哈希不够安全,高精度场景建议使用**双哈希**(两个 base 和 mod) ### 🔐 安全增强:双哈希法 ```c struct DoubleHash { long long h1, h2; }; ``` 分别用 base=31 和 base=131 计算两个哈希值,只有两者都相等才算相同字符串。 --- # 知识点 - **哈希函数设计原理** 将字符串视为多进制数,利用加权和生成唯一标识,实现快速比较。 - **防冲突字符编码** 字符偏移 `'a' -> 1` 避免前导零导致不同串哈希相同,提升准确性。 - **滚动哈希应用场景** 适用于子串匹配、去重、动态更新等场景,如 Rabin-Karp 算法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值