【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》

这篇具有很好参考价值的文章主要介绍了【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在最前面

主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。

内容补充:骆婷老师的PPT
《introduction to modern cryphtography》–Jonathan Katz, Yehuda Lindell(现代密码学——原理与协议)中相关章节
密码学复习笔记 这个博主好有意思

初步笔记,如有错误请指正

快速补充一些密码相关的背景知识


【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》,密码学,笔记,哈希算法,安全,gpt,算法,网络安全

4 消息认证码与抗碰撞哈希函数

  1. 本节学习用于保护信息的完整性和真实性的消息认证码(MAC)和抗碰撞的哈希函数(CRHF)。

  2. 目录:MAC、构建安全MAC、CBC-MAC、CRHF、HMAC、信息论上MAC。

  3. 完整性与真实性(Integrity and Authentication

    • 敌手篡改传输中的密文(或明文)是对完整性的攻击;
      敌手伪装成Alice发送密文(或明文)是对真实性(认证)的攻击;
    • 上述两种攻击可以归结为对真实性(认证)的攻击,消息是由敌手构造并发出的;
    • 注意,这里的真实性是指消息的来源是来自接受者所预期的发送者,不是指内容的真假!

MAC

  1. MAC的词法(Message Authentication Code
    【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》,密码学,笔记,哈希算法,安全,gpt,算法,网络安全

    • 密钥 k k k, 标签(tag) t t t, 一个比特 b b b 为有效的 (valid}) ,如果 b = 1 b=1 b=1;
      或 无效的 ​(invalid}​) ,如果 b = 0 b=0 b=0.
    • 密钥生成 Key-generation 算法 k ← G e n ( 1 n ) , ∣ k ∣ ≥ n k \gets \mathsf{Gen}(1^n), |k| \ge n kGen(1n),kn.
    • 标签生成 Tag-generation 算法 t ← M a c k ( m ) t \gets \mathsf{Mac}_k(m) tMack(m).
    • 验证 Verification 算法 b : = V r f y k ( m , t ) b:= \mathsf{Vrfy}_k(m,t) b:=Vrfyk(m,t).
    • 消息认证码 Message authentication code: Π = ( G e n , M a c , V r f y ) \Pi = (\mathsf{Gen}, \mathsf{Mac}, \mathsf{Vrfy}) Π=(Gen,Mac,Vrfy).
    • 基本正确性需求 Basic correctness requirement : V r f y k ( m , M a c k ( m ) ) = 1 \mathsf{Vrfy}_k(m,\mathsf{Mac}_k(m)) = 1 Vrfyk(m,Mack(m))=1.
    • 注:不同于加密方案,MAC并不需要从标签得到密文。
  2. MAC安全

    • 直觉上,没有敌手能够伪造一个从未被发送过的新消息的有效标签。这里“新消息”是为了排除“重放攻击”。
    • 重放攻击(Replay attack):敌手记录并发送之前的消息和标签,从而发送了一个伪造的消息并带有有效的标签;为了避免重放攻击,可以通过两种非密码学的方法。
      • 序列号:接收方需要记录之前的序列号,从而发现序列号较小(或曾经接收过的)的旧消息;
      • 时间戳:双方维护时钟同步,从而发现晚与当前时钟的旧消息;
      • 这两种方法都不依赖于密码学,因此,防御重放攻击不需要在密码学的范畴内考虑。
    • 存在性不可伪造(Existential unforgeability):不能伪造任何消息的标签,一个都不能伪造。
      • 存在性伪造 Existential forgery: 至少伪造一个消息的标签。
      • 选择性伪造 Selective forgery: 实施攻击前选择一个消息,并伪造该消息的标签。
      • 全域性伪造 Universal forgery: 伪造任意给定的消息的标签。
      • 最强的安全目标是阻止最弱的敌手造成的后果。
    • 适应性选择消息攻击(Adaptive chosen-message attack (CMA)):敌手在攻击过程中始终具有获得任意消息的有效标签的能力,即访问标签生成预言机;
  3. 定义MAC安全

    • 消息认证实验 M a c f o r g e A , Π ( n ) \mathsf{Macforge}_{\mathcal{A},\Pi }(n) MacforgeA,Π(n) 在挑战者和敌手之间:
      1. 挑战者生成密钥 k ← G e n ( 1 n ) k \gets \mathsf{Gen}(1^n) kGen(1n).
      2. 敌手 A \mathcal{A} A 具有访问标签生成算法 M a c k ( ⋅ ) \mathsf{Mac}_k(\cdot) Mack()的预言机的能力,并输出 ( m , t ) (m,t) (m,t). 对预言机查询的消息集合为 Q \mathcal{Q} Q
      3. M a c f o r g e A , Π ( n ) = 1    ⟺    \mathsf{Macforge}_{\mathcal{A},\Pi }(n)=1 \iff MacforgeA,Π(n)=1 V r f y k ( m , t ) = 1 \mathsf{Vrfy}_k(m,t)=1 Vrfyk(m,t)=1 ∧ \land m ∉ Q m \notin \mathcal{Q} m/Q. 敌手成功,如果输出的消息和标签通过了验证,并且输出的消息是从未向预言机查询过的新消息。
    • 定义:一个 MAC Π \Pi Π 是在适应性CMA下的存在性不可伪造 (existentially unforgeable under an adaptive CMA),如果 ∀ \forall PPT A \mathcal{A} A, ∃ \exists n e g l \mathsf{negl} negl 使得: Pr ⁡ [ M a c f o r g e A , Π ( n ) = 1 ] ≤ n e g l ( n ) . \Pr [\mathsf{Macforge}_{\mathcal{A},\Pi }(n)=1] \le \mathsf{negl}(n). Pr[MacforgeA,Π(n)=1]negl(n).
      如果对名称不熟悉,可以参考下方的概念回顾

概念回顾(是的,我忘记这些缩写是什么了。。)

PPT在密码学中代表“概率多项式时间”(Probabilistic Polynomial Time),这是一种衡量算法或攻击者能力的标准。在这个特定的上下文中,PPT是用来描述攻击者的计算能力。

让我们来详细解释这个定义:

MAC的定义
  • MAC:MAC代表“消息认证码”(Message Authentication Code),它是一种用于验证消息完整性和来源真实性的加密工具。
  • 存在性不可伪造:一个MAC系统被称为“存在性不可伪造”的,意味着没有攻击者可以成功地伪造一个有效的MAC(即使是一个新的、以前未见过的MAC),除非通过微不足道的概率。
适应性CMA(Chosen Message Attack)
  • 适应性CMA:适应性选择消息攻击(Adaptive Chosen Message Attack)是一种攻击模型,其中攻击者可以选择并获得先前消息的MAC值,然后尝试基于这些信息伪造新消息的MAC。
  • 存在性不可伪造:在适应性CMA环境下,存在性不可伪造意味着攻击者在选择任意消息并获取其MAC后,仍然无法伪造其他任何消息的MAC。
PPT攻击者
  • PPT攻击者:概率多项式时间攻击者是指那些拥有多项式时间计算能力的攻击者。这意味着他们的计算资源是有限的,不能进行无限的尝试或拥有无限的计算能力。
  • 重要性:在考虑密码系统的安全性时,通常假设攻击者是PPT的。这是一种现实的假设,因为实际中攻击者的资源是有限的。
不可忽略的概率(negl(n))
  • n e g l ( n ) \mathsf{negl}(n) negl(n):这是一个表示概率的术语,指的是某个函数随着输入大小的增长而增长得极其缓慢,以至于在实际中可以忽略不计。
  • 应用:在这个定义中,如果对于所有的PPT攻击者 A \mathcal{A} A,伪造MAC的概率 Pr ⁡ [ M a c f o r g e A , Π ( n ) = 1 ] \Pr [\mathsf{Macforge}_{\mathcal{A},\Pi }(n)=1] Pr[MacforgeA,Π(n)=1] 是可忽略的,那么就可以说这个MAC系统在适应性CMA下是存在性不可伪造的。
总结

所以,这个定义的含义是:一个MAC系统在适应性选择消息攻击下被认为是安全的,如果没有任何实际的、有限计算能力的攻击者能够以超过微不足道的概率成功伪造一个MAC。这个标准确保了即使在面对强大但现实的攻击者时,MAC系统也能保持其安全性和完整性。

案例

  1. 真实例子

    • WEP 802.11 MAC中的漏洞有两点
    • 一是存在不同消息的CRC32可能是一样的情况,而且这种情况很容易给出。那么,敌手可以查询一个消息 m m m并得到对应的标签 t t t;然后,输出另一个与所查询消息 m m m具有相同CRC32值的新消息 m ′ m' m,以及查到的标签 t t t
    • 二是敌手可以查询一个消息 m ′ m' m并获得标签 ( r , t ′ ) (r, t') (r,t),由此计算得到 F ( k , r ) = t ′ ⊕ C R C 32 ( m ′ ) F(k,r) = t'\oplus \mathsf{CRC32}(m') F(k,r)=tCRC32(m);输出一个新消息 m m m以及标签 t = ( r , F ( k , r ) ⊕ C R C 32 ( m ) ) t = (r, F(k,r)\oplus\mathsf{CRC32}(m)) t=(r,F(k,r)CRC32(m))
    • 上述漏洞展现了攻击MAC的两种常用手段:一是找到两个消息得到相同的中间结果,从而以一个消息的标签作为另一个新消息的标签;二是利用对一个/多个消息的标签来获得构造标签所需的信息,从而构造一个新消息的标签。
  2. 例题

    • 如果认为是安全的,则要用反证法证明,若新方案不安全,则原方案也不安全;
    • 如果认为是不安全的,则给出一个新消息和对应的标签;
  3. MAC应用

    • Web cookie:Web服务器在发给浏览器的cookie中包含自己生成的MAC标签,来阻止攻击者伪造其他用户的cookie;
    • TCP SYN cookie:在TCP三次握手中,服务器在其发给客户端的初始序列号中包含一个服务器生成的MAC标签,来避免保留握手状态,从而防御SYN Flooding DDoS攻击;
    • 临时一次口令:用户发送给服务器的临时登录口令为一个MAC标签 p = M a c k ( T ) p=\mathsf{Mac}_k(T) p=Mack(T),其中 k k k为原始口令, T T T为当前时间(按半分钟取整);敌手窃听了之前的临时口令也无法伪造未来的临时口令;

构建安全MAC

  1. 构造安全MAC

    • 基于PRF构造安全MAC
      • F F F 是 PRF. ∣ m ∣ = n |m| = n m=n.
      • G e n ( 1 n ) \mathsf{Gen}(1^n) Gen(1n): k ← { 0 , 1 } n k \gets \{0,1\}^n k{0,1}n .
      • M a c k ( m ) \mathsf{Mac}_k(m) Mack(m): t : = F k ( m ) t := F_k(m) t:=Fk(m).
      • V r f y k ( m , t ) \mathsf{Vrfy}_k(m,t) Vrfyk(m,t): 1    ⟺    t = ? F k ( m ) 1 \iff t \overset{?}{=} F_k(m) 1t=?Fk(m).
    • 定理:如果 F F F 是一个PRF,那么上述构造是安全的固定长度 MAC。
    • 引理:如果 F F F 是一个 PRF,那么 F k t ( m ) = F k ( m ) [ 1 , … , t ] F^t_k(m) = F_k(m)[1,\dots,t] Fkt(m)=Fk(m)[1,,t] 也是一个PRF。
      • 注:这个引理说明部分输出仍保留伪随机性。引理成立的原因在于,如果根据更短的输出可以区分出伪随机函数,那么根据原长度输出也可以区分出伪随机函数了。
  2. 证明基于PRF的安全MAC

    • 证明思路是从PRF的区分器算法 D D D规约到伪造标签的敌手算法 A \mathcal{A} A D D D作为 A \mathcal{A} A的挑战者,用 D D D要区分的预言机作为 A \mathcal{A} A的标签生成预言机;当 A \mathcal{A} A伪造标签成功时, D D D输出1。
  3. 证明基于PRF的安全MAC(续)

    • 如果是真随机 f f f 被使用 t = f ( m ) t=f(m) t=f(m) 是均匀随机的.

      Pr ⁡ [ D f ( ⋅ ) ( 1 n ) = 1 ] = Pr ⁡ [ M a c f o r g e A , Π ~ ( n ) = 1 ] ≤ 2 − n . \Pr[D^{f(\cdot)}(1^n)=1] = \Pr[\mathsf{Macforge}_{\mathcal{A},\tilde{\Pi}}(n) = 1] \le 2^{-n}. Pr[Df()(1n)=1]=Pr[MacforgeA,Π~(n)=1]2n.

    • 如果 F k F_k Fk 被使用,那么就是在执行实验 M a c f o r g e A , Π ( n ) \mathsf{Macforge}_{\mathcal{A},\Pi}(n) MacforgeA,Π(n).

      Pr ⁡ [ D F k ( ⋅ ) ( 1 n ) = 1 ] = Pr ⁡ [ M a c f o r g e A , Π ( n ) = 1 ] = ε ( n ) . \Pr[D^{F_k(\cdot)}(1^n)=1] = \Pr[\mathsf{Macforge}_{\mathcal{A},\Pi}(n) = 1] = \varepsilon(n). Pr[DFk()(1n)=1]=Pr[MacforgeA,Π(n)=1]=ε(n).

    • 根据PRF的定义有, ∣ Pr ⁡ [ D F k ( ⋅ ) ( 1 n ) = 1 ] − Pr ⁡ [ D f ( ⋅ ) ( 1 n ) = 1 ] ∣ ≥ ε ( n ) − 2 − n . \left| \Pr[D^{F_k(\cdot)}(1^n)=1] - \Pr[D^{f(\cdot)}(1^n)=1] \right| \ge \varepsilon(n) - 2^{-n}. Pr[DFk()(1n)=1]Pr[Df()(1n)=1]ε(n)2n.

  4. 扩展到变长消息

    • 对于变长消息,下面的建议是安全的吗?
    • 建议1:将所有块异或后,对结果进行认证: t : = M a c k ′ ( ⊕ i m i ) t := \mathsf{Mac}_k'(\oplus_i m_i) t:=Mack(imi)
    • 建议2:对每个块分别认证, t i : = M a c k ′ ( m i ) t_i := \mathsf{Mac}_k'(m_i) ti:=Mack(mi)
    • 建议3:对每个块连带一个序列号一起认证, t i : = M a c k ′ ( i ∥ m i ) t_i := \mathsf{Mac}_k'(i\| m_i) ti:=Mack(imi).

CBC-MAC

CBC概念回顾

CBC-MAC(Cipher Block Chaining Message Authentication Code)是一种基于块加密算法的消息认证码(MAC)构造方法。它使用的是密码块链接(Cipher Block Chaining,CBC)模式,这是一种常用的块加密操作模式。

构造固定长度的CBC-MAC

  1. 构造固定长度的CBC-MAC

    • 为了构造用于变长消息的MAC,先学习固定长度的CBC-MAC,其与CBC结构类似,做了两处改变:
    • 改动1:将初始向量IV改为0;如果不这样改动,则敌手查询 m 1 m_1 m1 并获得 ( I V , t 1 ) (IV, t_1) (IV,t1);然后,输出 m 1 ′ = I V ′ ⊕ I V ⊕ m 1 m_1' = IV' \oplus IV \oplus m_{1} m1=IVIVm1 并且 t ′ = ( I V ′ , t 1 ) t' = (IV',t_1) t=(IV,t1),一个有效的标签。
    • 改动2:标签只包括最后一个块的输出;如果不这样改动,则敌手查询 m i m_i mi 并得到 t i t_i ti;然后,输出 m i ′ = t i − 1 ′ ⊕ t i − 1 ⊕ m i m_i' = t_{i-1}' \oplus t_{i-1} \oplus m_{i} mi=ti1ti1mi 以及 t i ′ = t i t_{i}' = t_i ti=ti,一个有效的标签。
  2. 构造固定长度的CBC-MAC(续)

    • 定理:如果 F F F是一个PRF,那么上面的构造就是一个安全的固定长度MAC。
    • 这个构造不能用于变长消息,因为对于一个块的消息 m m m和标签 t t t,敌手可以在其后添加一个块 m ⊕ t m\oplus t mt并且输出标签 t t t
  3. 安全变长MAC

    • 有三种方法可以将CBC-MAC改造为用于变长消息的MAC,都可以防御上面在结尾添加新块的攻击。
    • 输入长度密钥分离: k ℓ : = F k ( ℓ ) k_{\ell} := F_k(\ell) k:=Fk(), 用 k ℓ k_{\ell} k 作为 CBC-MAC 的密钥。不同长度下采用不同密钥,追加新块后长度变化,之前的标签无法利用。
    • 在开头添加长度:在CBC-MAC的明文 m m m前添加一个长度块 ∣ m ∣ |m| m。不同长度下消息有不同的初始块,追加新块后长度变化,之前的标签无法利用。
    • 加密末块输出(ECBC-MAC):采用两个密钥 k 1 , k 2 k_1, k_2 k1,k2。用 k 1 k_1 k1和CBC-MAC计算出 t t t,然后输出 t ^ : = F k 2 ( t ) \hat{t} := F_{k_2}(t) t^:=Fk2(t)。输出结果被加密,之前的标签无法利用。
  4. MAC填充(Padding

    • 与加密类似,为了将消息长度与块长度对齐,MAC中也需要在消息中填充。为了安全性,需要保证填充是可逆的,即不同的消息在填充后也应该不同!
    • m 0 ≠ m 1 ⇒ p a d ( m 0 ) ≠ p a d ( m 1 ) . m_0\neq m_1 \Rightarrow \mathsf{pad}(m_0) \neq \mathsf{pad}(m_1). m0=m1pad(m0)=pad(m1).
    • ISO的填充标准:用“100…00”填充,并按需填充哑块。
    • 如果不填充哑块,则会导致什么?
    • CMAC(Cipher-based MAC):不填充哑块,不加密最后一块的输出,密钥包括三个 k , k 1 , k 2 k, k_1, k_2 k,k1,k2
      • k k k用于CBC-MAC;
      • k 1 k_1 k1 k 2 k_2 k2 与最后一块消息异或来阻止利用最后一块输出;
      • k 1 k_1 k1 k 2 k_2 k2 来区分是否添加了哑块。

CRHF:哈希函数Hash Function、 定义抗碰撞Collision Resistance

  1. 定义哈希函数(Hash Function

    • 一个哈希函数 (压缩函数) 是一对PPT算法 ( G e n , H ) (\mathsf{Gen}, H) (Gen,H) 满足以下条件:
      • 一个密钥 s ← G e n ( 1 n ) s \gets \mathsf{Gen}(1^n) sGen(1n) s s s 不保密.
      • H s ( x ) ∈ { 0 , 1 } ℓ ( n ) H^s(x) \in \{0,1\}^{\ell(n)} Hs(x){0,1}(n), 其中 x ∈ { 0 , 1 } ∗ x \in \{0,1\}^* x{0,1} ℓ \ell 为多项式。
    • H s H^s Hs 只在 x ∈ { 0 , 1 } ℓ ′ ( n ) x \in \{0,1\}^{\ell'(n)} x{0,1}(n) 上定义并且 ℓ ′ ( n ) > ℓ ( n ) \ell'(n) > \ell(n) (n)>(n),那么 ( G e n , H ) (\mathsf{Gen}, H) (Gen,H) 是固定长度的哈希函数。
    • 上面的定义说明,哈希函数将长消息转变为短消息。
  2. 定义抗碰撞(Collision Resistance

    • 碰撞(Collision): x ≠ x ′ x \neq x' x=x 并且 H ( x ) = H ( x ′ ) H(x) = H(x') H(x)=H(x)

    • 抗碰撞(Collision Resistance):对于任意PPT算法,找到碰撞是不可能的。

    • 碰撞发现实验 H a s h c o l l A , Π ( n ) \mathsf{Hashcoll}_{\mathcal{A},\Pi}(n) HashcollA,Π(n):

      • s ← G e n ( 1 n ) s \gets \mathsf{Gen}(1^n) sGen(1n).

        • 敌手 A \mathcal{A} A 输入 s s s ,输出 x , x ′ x, x' x,x. 注:敌手有 s s s,意味着可以访问哈希函数
      • H a s h c o l l A , Π ( n ) = 1    ⟺    x ≠ x ′ ∧ H s ( x ) = H s ( x ′ ) \mathsf{Hashcoll}_{\mathcal{A},\Pi}(n) =1 \iff x\ne x' \land H^s(x) = H^s(x') HashcollA,Π(n)=1x=xHs(x)=Hs(x).

      • 哈希函数 Π \Pi Π ( G e n \mathsf{Gen} Gen, H s H^s Hs) 是抗碰撞的,如果 ∀ \forall ppt A \mathcal{A} A ∃    n e g l \exists\;\mathsf{negl} negl 使得
        Pr ⁡ [ H a s h c o l l A , Π ( n ) = 1 ] ≤ n e g l ( n ) . \Pr[\mathsf{Hashcoll}_{\mathcal{A},\Pi}(n)=1] \le \mathsf{negl}(n). Pr[HashcollA,Π(n)=1]negl(n).

  3. 哈希函数安全的更弱的概念

    • 抗碰撞(Collision resistance): 难以找到 ( x , x ′ ) , x ′ ≠ x (x, x'), x' \ne x (x,x),x=x 使得 H ( x ) = H ( x ′ ) H(x) = H(x') H(x)=H(x).
    • 抗二次原像 (Second pre-image resistance): 给定 s s s x x x, 难以发现 x ′ ≠ x x' \ne x x=x 使得 H s ( x ′ ) = H s ( x ) H^s(x') = H^s(x) Hs(x)=Hs(x).
    • 抗原像 (Pre-image resistance): 给定 s s s y = H s ( x ) y = H^s(x) y=Hs(x), 难以发现 x ′ x' x 使得 H s ( x ′ ) = y H^s(x')=y Hs(x)=y.
    • 攻击越难,反过来可以防范这种攻击的安全性就越弱。
  4. 关于CRHF的问题

    • 如果认为不是,那么请给出一个碰撞;
    • 如果认为是,则用反证法证明找到了 H ′ H' H的碰撞意味着 H H H的碰撞。
  5. 哈希函数的应用

    • 文件指纹和去重(Fingerprinting 和 Deduplication):识别一个文件,用于病毒指纹识别,去重复,P2P文件共享;
    • 默克尔树 (Merkle Tree):构造多个文件或一个文件多个部分的指纹,从而定位有问题的文件或者文件中的部分;
    • 口令哈希(Password Hashing): ( s a l t , H ( s a l t , p w ) ) (salt, H(salt, pw)) (salt,H(salt,pw)),缓解明文口令泄漏风险;
    • 密钥派生(Key Derivation):从一个高熵(但不必均匀随机)的共享秘密中派生一个密钥;
    • 承诺方案(Commitment Scheme):将一个承诺与一份信息绑定,隐藏承诺的信息;例如,互联网上掷硬币。
  6. 生日问题

    • 生日问题:“如果一群人中有两个人的生日是同一天的概率有1/2,这群人数有多少?”。答案是23。这与我们平时的认知差异,也被称作“生日悖论”。具体计算见教材附件。
      【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》,密码学,笔记,哈希算法,安全,gpt,算法,网络安全

    • 这个问题意味着哈希函数的输出需要足够长,否则敌手可能通过蛮力枚举来发现碰撞。

    • 在现实攻击中,找到有意义的消息的碰撞对于攻击者来说更有价值。这对攻击者来说并不是难题,可以很容易的构造足够数量的、有意义的消息来实施攻击。对消息中一个单词的替换,所构造明文的数量翻番。

  7. MD变换(Merkle-Damgård Transform

    • 从定长哈希函数 ( G e n , h ) (\mathsf{Gen}, h) (Gen,h) ( 2 ℓ 2\ell 2 bits → ℓ \to \ell bits, ℓ = ℓ ( n ) \ell = \ell(n) =(n))构造变长哈希函数 CRHF ( G e n , H ) (\mathsf{Gen}, H) (Gen,H) :
      • G e n \mathsf{Gen} Gen: 不变
      • H H H: 密钥 s s s 与串 x ∈ { 0 , 1 } ∗ x \in \{0,1\}^* x{0,1}, L = ∣ x ∣ < 2 ℓ L=|x|< 2^{\ell} L=x<2:
        • B : = ⌈ L ℓ ⌉ B := \lceil \frac{L}{\ell} \rceil B:=L (块数)。 用0填充。 ℓ \ell -位的块 x 1 , … , x B x_1,\dotsc,x_B x1,,xB。最后一块是长度 x B + 1 : = L x_{B+1} := L xB+1:=L L L L ℓ \ell 位编码,这是必要的,因为只用0填充会导致不同消息的输入是一样的。
        • z 0 : = I V = 0 ℓ z_0 := IV = 0^\ell z0:=IV=0。 对于 i = 1 , … , B + 1 i=1,\dotsc,B+1 i=1,,B+1, 计算 z i : = h s ( z i − 1 ∥ x i ) z_i := h^s(z_{i-1}\| x_i) zi:=hs(zi1xi)
  8. MD变换的安全性

    • 定理:如果 h h h是定长CRHF,那么 H H H也是CRHF。
    • 证明:思路是 H H H上的碰撞意味着 h h h上的碰撞,而 h h h是不会被找到碰撞的。两个消息 x ≠ x ′ x \ne x' x=x ,长度分别为 L L L L ′ L' L ,块数分别为 B B B B ′ B' B,使得 H s ( x ) = H s ( x ′ ) H^s(x) = H^s(x') Hs(x)=Hs(x)。 有两种情况:
      • L ≠ L ′ L \ne L' L=L: z B ∥ L ≠ z B ′ ∥ L ′ z_B\| L \ne z_{B'}\| L' zBL=zBL;长度不同,意味着最后一个哈希函数 h h h的输入不同,但输出相同,发现碰撞。
      • L = L ′ L = L' L=L: z i ∗ − 1 ∥ x i ∗ ≠ z i ∗ − 1 ′ ∥ x i ∗ ′ z_{i^*-1}\| x_{i^*} \ne z_{i^*-1}'\| x_{i^*}' zi1xi=zi1xi;长度相同,意味着中间某一块的输入不同,但输出相同,发现碰撞。
      • 因此,必定有 x ≠ x ′ x \neq x' x=x 使得 h s ( x ) = h s ( x ′ ) h^s(x) = h^s(x') hs(x)=hs(x)
    • 作业中有关于MD变换的变体的安全性分析问题。
  9. 从分组密码构造CRHF

    • 可以从块密码来构造CRHF,例如Davies-Meyer方法 (SHA-1/2, MD5) h i = F m i ( h i − 1 ) ⊕ h i − 1 h_{i} = F_{m_{i}}(h_{i-1}) \oplus h_{i-1} hi=Fmi(hi1)hi1,或者 Miyaguchi-Preneel 方法 (Whirlpool) h i = F h i − 1 ( m i ) ⊕ h i − 1 ⊕ m h_{i} = F_{h_{i-1}}(m_{i}) \oplus h_{i-1} \oplus m hi=Fhi1(mi)hi1m
    • 定理:如果 F F F是一个理想的加密方案,那么Davies-Meyer构造得到一个CRHF。注:理想的加密方案参考后面要学习的随机预言机模型。目前,没有找到 F F F是强伪随机排列下该方法是CRHF的证明。
    • 对于这个定理不做严格证明,而是回答两个问题:
      • 如果 h i = F m i ( h i − 1 ) h_{i} = F_{m_{i}}(h_{i-1}) hi=Fmi(hi1) ,不与 h i − 1 h_{i-1} hi1 异或,会如何?敌手尝试以相同的 h i h_i hi和不同的 m i m_i mi F F F求逆。
      • 如果 F F F 不是理想的,而是 ∃ x , F k ( x ) = x \exists x, F_k(x)=x x,Fk(x)=x,会如何?敌手输入不同 m i m_i mi,但都得到0;
  10. SHA-1和MD5

    • 曾将广泛采用的哈希函数SHA1和MD5都已经被破解。对于128位的MD5,找到碰撞需要 2 20.96 2^{20.96} 220.96;对于160位的SHA1,找到碰撞需要 2 51 2^{51} 251

HMAC

  1. Hash-and-MAC

    • 有了CRHF,一个自然的想法是:先将任意长度消息哈希,然后通过PRF对哈希值做MAC,实现任意长度消息MAC。 F k ( H ( m ) ) F_k(H(m)) Fk(H(m))
    • 这个方案的安全性分两种情况分析:当不同消息得到相同哈希值时,这意味着碰撞发生;否则,意味着MAC标签被伪造。
  2. NMAC

    • 使用CRHF(MD变换)来构造MAC,而不需要用PRF
    • 之所以需要开头的密钥,是为了在哈希函数为弱抗碰撞性时也保障安全;如果哈希函数是CRHF,则不需要开头的密钥
    • 缺点:需要修改哈希函数(MD变换中初始向量)
  3. HMAC(基于哈希的MAC)

    • 以MD变换为基础构造一个安全的MAC。在开头和结尾以两个不同密钥作为哈希函数输入。
    • 不需要修改哈希函数。
    • G e n ( 1 n ) \mathsf{Gen}(1^n) Gen(1n): 输出 ( s , k ) (s, k) (s,k). s ← G e n ~ , k ← { 0 , 1 } n s \gets \widetilde{\mathsf{Gen}}, k \gets \{0,1\}^n sGen ,k{0,1}n u.a.r;
    • M a c s , k ( m ) \mathsf{Mac}_{s,k}(m) Macs,k(m): t : = H I V s ( ( k ⊕ o p a d ) ∥ H I V s ( ( k ⊕ i p a d ) ∥ m ) ) t := H_{IV}^s\Big((k \oplus \mathsf{opad}) \| H_{IV}^s\big((k \oplus \mathsf{ipad}) \| m\big)\Big) t:=HIVs((kopad)HIVs((kipad)m))
    • V r f y s , k ( m , t ) \mathsf{Vrfy}_{s,k}(m,t) Vrfys,k(m,t): 1    ⟺    t = ? M a c s , k ( m ) 1 \iff t \overset{?}{=} \mathsf{Mac}_{s,k}(m) 1t=?Macs,k(m)
  4. HMAC安全性

    • 定理: G ( k ) = def h s ( I V ∥ ( k ⊕ o p a d ) ) ∥ h s ( I V ∥ ( k ⊕ i p a d ) ) = k 1 ∥ k 2 G(k) \overset{\text{def}}{=} h^s(IV\| (k\oplus \mathsf{opad})) \| h^s(IV\| (k\oplus \mathsf{ipad})) = k_1\| k_2 G(k)=defhs(IV(kopad))hs(IV(kipad))=k1k2 。其中, h h h是CRHF。如果 G G G是PRG,那么HMAC是安全的。
    • 在HMAC之前,其他不安全的方案包括:
    • H s ( k ∥ x ) H^s(k\| x) Hs(kx) 存在长度扩展攻击弱点。 在获得 H s ( k ∥ x ) H^s(k\| x) Hs(kx)和消息长度后,敌手能够获得新消息 x ∥ x ′ x \| x' xx 的有效标签 H s ( k ∥ x ∥ x ′ ) H^s(k\| x \| x') Hs(kxx) 。因为 H s ( k ∥ x ) H^s(k\| x) Hs(kx)的输出标签 t t t x ′ x' x作为哈希函数的输入直接得到输出。
    • H s ( x ∥ k ) H^s(x\| k) Hs(xk): 在一个弱哈希函数上的碰撞会导致MAC上碰撞。回顾NMAC中需要开头的密钥来支持弱抗碰撞的情况。
    • H s ( k ∥ x ∥ k ) H^s(k\| x\| k) Hs(kxk): 也存在一些已知的弱点,即使使用两个不同的密钥。
    • H s ( k ∥ H s ( k ∥ x ) ) H^s(k \| H^s(k \| x)) Hs(kHs(kx)):这是NMAC和HMAC的情况
  5. HMAC结语

    • HMAC是基于NMAC的改进,是工业标准(RFC2104),HMAC比CBC-MAC更快;

    • 验证计时攻击:

      • Keyczar密码学库(Python):

      • def Verify(key, msg, sig_bytes):

        \qquad return HMAC(key, msg) == sig_bytes

      • 存在问题是上述比较是按字节匹配,通过观察函数返回时间可以判断相同字节的数量,从而按字节猜测标签内容。

      • 在Xbox 360中,相邻字节上被验证拒绝的时间差有2.2毫秒.

    • 不要自己实现密码学!

信息论上MAC

  1. 信息论上MAC安全定义

    • 不可能达到“完美的、不可伪造的”MAC,因为算力无限制的敌手可以至少以 1 / 2 ∣ t ∣ 1/2^{|t|} 1/2t 的概率输出一个有效的标签。为此,对敌手查询MAC预言机的次数需要加以限制,下面分析只允许敌手查询一次MAC预言机的情况。
    • 一次消息认证实验 M a c f o r g e A , Π 1 − t i m e \mathsf{Macforge}^{\mathsf{1-time}}_{\mathcal{A},\Pi } MacforgeA,Π1time: 敌手查询一次MAC预言机后输出消息和标签,
      • k ← G e n k \gets \mathsf{Gen} kGen.
      • A \mathcal{A} A 输出一个消息 m ′ m' m并且获得一个标签 t ′ ← M a c k ( m ′ ) t' \gets \mathsf{Mac}_k(m') tMack(m), 然后输出 ( m , t ) (m,t) (m,t).
      • M a c f o r g e A , Π 1 − t i m e = 1    ⟺    \mathsf{Macforge}^{\mathsf{1-time}}_{\mathcal{A},\Pi }=1 \iff MacforgeA,Π1time=1 V r f y k ( m , t ) = 1 \mathsf{Vrfy}_k(m,t)=1 Vrfyk(m,t)=1 ∧ \land m ≠ m ′ m \neq m' m=m.
    • 定义:一个MAC Π \Pi Π 是一次 ε \varepsilon ε-安全的(one-time ε \varepsilon ε-secure),如果 ∀ \forall ppt A \mathcal{A} A: Pr ⁡ [ M a c f o r g e A , Π 1 − t i m e = 1 ] ≤ ε . \Pr [\mathsf{Macforge}^{\mathsf{1-time}}_{\mathcal{A},\Pi}=1] \le \varepsilon. Pr[MacforgeA,Π1time=1]ε.
    • 这里 ε \varepsilon ε应该为 1 / 2 ∣ t ∣ 1/2^{|t|} 1/2t,才能达到之前的信息论安全。信息论安全的MAC在允许敌手查询MAC预言机若干次之后,成功伪造MAC的概率应该不大于 1 / 2 ∣ t ∣ 1/2^{|t|} 1/2t
  2. 理解信息论MAC安全

    • 假设敌手算法是确定性的,其最合理的步骤如下:
      • (1)选择的 m ′ m' m是固定的,查询得到 t ′ t' t
      • (2)根据 m ′ m' m t ′ t' t确定 k k k的所有可能集合 K ( t ′ ) \mathcal{K}(t') K(t),从中选择一个 k ∗ k^* k
      • (3)选择输出 m m m是固定的,根据 k ∗ k^* k计算 t t t并输出。
    • 问题: K ( t ′ ) \mathcal{K}(t') K(t)太大或太小会如何?
    • 设想如果根据第一次消息和标签能够唯一确定密钥 k k k,那么敌手一定可以成功伪造;反之,如果不能唯一确定密钥,并且密钥可能的范围 K ( t ′ ) \mathcal{K}(t') K(t)充分大,那么敌手就难以成功伪造。从另一个角度,需要第一次查询获得的一个对消息和标签与敌手伪造另一个新消息的标签这两个事件之间是充分独立的。密钥空间太大也不安全,因为令 ( m , t ) (m, t) (m,t)是有效标签密钥集合也更大,其概率也增大。
  3. 信息论上MAC的构造

    • 一个函数 h h h: K × M → T \mathcal{K} \times \mathcal{M} \to \mathcal{T} K×MT 是一个强全域函数(Strongly Universal Function (SUF)),如果对于所有不同的 m , m ′ ∈ M m, m' \in \mathcal{M} m,mM 以及所有 t , t ′ ∈ T t, t' \in \mathcal{T} t,tT, 以下成立: Pr ⁡ [ h k ( m ) = t ∧ h k ( m ′ ) = t ′ ] = 1 / ∣ T ∣ 2 \Pr [h_k(m) = t \land h_k(m') = t'] = 1 / |\mathcal{T}|^2 Pr[hk(m)=thk(m)=t]=1/T2,其中概率来自均匀选择的 k ∈ K k \in \mathcal{K} kK.
    • 为了实现一次 1 / 2 ∣ t ∣ 1/2^{|t|} 1/2t-安全的MAC,需要一个新的数学对象,不同输入会独立产生不同的输出,输入间任何差异都会导致输出之间是完全独立的。将函数的这种性质称为:“成对独立的,pairwise-independent” 或者 “成对不可预测,pairwise-unpredictable”。
    • SUF是具有上面性质的函数,下一页证明
    • 信息论安全MAC构造:
      • h h h: K × M → T \mathcal{K} \times \mathcal{M} \to \mathcal{T} K×MT 为一个SUF.
      • G e n \mathsf{Gen} Gen: k ← { 0 , 1 } n k \gets \{0,1\}^n k{0,1}n u.a.r.
      • M a c k ( m ) \mathsf{Mac}_k(m) Mack(m): t : = h k ( m ) t := h_k(m) t:=hk(m).
      • V r f y k ( m , t ) \mathsf{Vrfy}_k(m,t) Vrfyk(m,t): 1    ⟺    t = ? h k ( m ) 1 \iff t \overset{?}{=} h_k(m) 1t=?hk(m). (如果 m ∉ M m \notin \mathcal{M} m/M,那么输出 0.)
  4. 构造一个SUF

    • 定理:对于任意质数 P P P,函数 h h h 是一个SUF: h a , b ( m ) = d e f [ a ⋅ m + b m o d    p ] h_{a,b}(m) \overset{\mathsf{def}}{=} [ a \cdot m + b \mod p] ha,b(m)=def[am+bmodp]
    • 证明: h a , b ( m ) = t h_{a,b}(m) = t ha,b(m)=t h a , b ( m ′ ) = t ′ h_{a,b}(m') = t' ha,b(m)=t,只有当 a ⋅ m + b = t m o d    p a \cdot m + b = t \mod p am+b=tmodp a ⋅ m ′ + b = t ′ m o d    p a \cdot m' + b = t' \mod p am+b=tmodp. 我们有 a = [ ( t − t ′ ) ⋅ ( m − m ′ ) − 1 m o d    p ] a = [(t-t') \cdot (m - m')^{-1} \mod p] a=[(tt)(mm)1modp] b = [ t − a ⋅ m m o d    p ] b = [t - a \cdot m \mod p] b=[tammodp],这意味着存在一个唯一的密钥 ( a , b ) (a, b) (a,b)。由于存在 ∣ T ∣ 2 |\mathcal{T}|^2 T2 个密钥, Pr ⁡ [ h k ( m ) = t ∧ h k ( m ′ ) = t ′ ] = 1 ∣ T ∣ 2 \Pr [h_k(m) = t \land h_k(m') = t'] = \frac{1}{|\mathcal{T}|^2} Pr[hk(m)=thk(m)=t]=T21
  5. 来自SUF的MAC的安全性

    • 定理:如果 h h h 是一个 SUF,构造是一个 1 / ∣ T ∣ − 1/|\mathcal{T}|- 1/T安全MAC.
    • 证明:假设敌手算法是确定性的,不失一般性可以固定 m ′ m' m并遍历所有可能的 t ′ t' t,敌手以 ( m ′ , t ′ ) (m', t') (m,t)作为输入并输出 ( m , t ) (m, t) (m,t)。根据SUF的定义,可以得到敌手成功的概率为 1 / ∣ T ∣ 1/|\mathcal{T}| 1/T
  6. 信息论MAC的局限性

    • 任意 ℓ \ell 2 − n 2^{-n} 2n-安全 MAC 需要密钥长度至少为 ( ℓ + 1 ) ⋅ n (\ell +1) \cdot n (+1)n.
    • 定理:令 Π \Pi Π 为一次 2 − n 2^{-n} 2n-安全 MAC,其中所有密钥长度相同。那么,密钥必须具有 2 n 2n 2n长度。
    • 证明:直觉上,每对消息和标签成立需要 2 n 2^n 2n个密钥,才能保证 2 − n 2^{-n} 2n-安全。一共2对,需要 2 2 n 2^{2n} 22n
    • K ( t ′ ) = d e f { k ∣ V r f y k ( m ′ , t ′ ) = 1 } \mathcal{K}(t') \overset{\mathsf{def}}{=} \{ k | \mathsf{Vrfy}_k(m', t') = 1\} K(t)=def{kVrfyk(m,t)=1},即所有由所查询消息得到标签的密钥集合。对于任意 t ′ t' t ∣ K ( t ′ ) ∣ ≤ 2 − n ⋅ ∣ K ∣ |\mathcal{K}(t')| \leq 2^{-n} \cdot |\mathcal{K}| K(t)2nK。 否则,敌手 A \mathcal{A} A从全体密钥集合中随机挑选一个密钥得到 ( m , t ) (m, t) (m,t) 是一个有效标签的概率至少为 ∣ K ( t ′ ) ∣ / ∣ K ∣ > 2 − n |\mathcal{K}(t')|/|\mathcal{K}|> 2^{-n} K(t)/K>2n,这与安全要求矛盾。 A \mathcal{A} A有无限算力可以根据从第一次查询中得到对应的密钥集合 K ( t ′ ) \mathcal{K}(t') K(t),从中选择一个密钥 k ∗ k^* k,并输出一个新消息 m m m的有效标签的概率是至少 1 ∣ K ( t ′ ) ∣ \frac{1}{|\mathcal{K}(t')|} K(t)1。固定 m ′ m' m遍历所有标签 t ′ t' t计算敌手成功概率为: ∑ t ′ Pr ⁡ [ M a c k ( m ′ ) = t ′ ] ⋅ 1 ∣ K ( t ′ ) ∣ ≥ ∑ t ′ Pr ⁡ [ M a c k ( m ′ ) = t ′ ] ⋅ 2 n ∣ K ∣ = 2 n ∣ K ∣ \sum_{t'} \Pr [\mathsf{Mac}_k(m') = t'] \cdot \frac{1}{|\mathcal{K}(t')|} \geq \sum_{t'} \Pr [\mathsf{Mac}_k(m') = t'] \cdot \frac{2^n}{|\mathcal{K}|} = \frac{2^n}{|\mathcal{K}|} tPr[Mack(m)=t]K(t)1tPr[Mack(m)=t]K2n=K2n 。由于概率至多 2 − n 2^{-n} 2n, ∣ K ∣ ≥ 2 2 n |\mathcal{K}| \geq 2^{2n} K22n。由于所有密钥具有相同长度,每个密钥的长度至少是 2 n 2n 2n
  7. 总结文章来源地址https://www.toymoban.com/news/detail-799579.html

    • 认证意味着存在不可伪造
    • 用PRF来实现安全MAC
    • 用带密钥的CRHF来实现安全MAC
    • 信息论MAC安全需要非常、非常长的密钥

到了这里,关于【现代密码学】笔记4--消息认证码与抗碰撞哈希函数《introduction to modern cryphtography》的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【现代密码学】笔记6--伪随机对象的理论构造《introduction to modern cryphtography》

    主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。 内容补充:骆婷老师的PPT 《introduction to modern cryphtography》–Jonathan Katz, Yehuda Lindell(现代密码学——原理与协议)中相关章节 密码学复习笔记 这个博主好有意思 初步笔记,如有错误请指正 快速补充一些密码

    2024年01月16日
    浏览(38)
  • 【11.10】现代密码学1——密码学发展史:密码学概述、安全服务、香农理论、现代密码学

    参考:密码学发展简史 骆婷老师的《现代密码学(32H)》课程,笔记+查找的资料补充 期末为闭卷考试的形式 密码学早在公元前400多年就已经产生,人类使用密码的历史几乎与使用文字的时间一样长,密码学的发展大致可以分为 3 个阶段: 1949年之前的古典密码学阶段; 1949 年

    2024年02月04日
    浏览(48)
  • 【现代密码学】笔记3.1-3.3 --规约证明、伪随机性《introduction to modern cryphtography》

    主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。 内容补充:骆婷老师的PPT 《introduction to modern cryphtography》–Jonathan Katz, Yehuda Lindell(现代密码学——原理与协议)中相关章节 密码学复习笔记 这个博主好有意思 B站视频 密码学原理《Introduction to modern Cryptog

    2024年01月20日
    浏览(46)
  • 【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》

    主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。 内容补充:骆婷老师的PPT 《introduction to modern cryphtography》–Jonathan Katz, Yehuda Lindell(现代密码学——原理与协议)中相关章节 密码学复习笔记 这个博主好有意思 初步笔记,如有错误请指正 快速补充一些密码

    2024年01月24日
    浏览(43)
  • 现代密码学复习

    目录 密码学总结 第一章——只因础模型与概念 1.1 密码学五元组(结合🐏皮卷) 1.2 Dolev-Yao威胁模型 1.3 攻击类型 1.4 柯克霍夫原则(Kerckhoffs\\\'s principle) 1.5 对称、非对称加密 1.6 密码的目标 1.7 保密通信模型 第二章——古典密码 2.1 仿射密码 2.2 Hill密码 例题0 ——解同余方程

    2023年04月09日
    浏览(59)
  • 现代密码学基础(2)

    目录 一. 介绍 二. 举例:移位密码 (1)密文概率 (2)明文概率 三. 举例:多字母的移位密码 四. 完美安全 五. 举例:双子母的移位密码 六. 从密文角度看完美安全 七. 完美保密性质 在密码学中,K代表密钥,M代表明文,C代表密文,每个都有各自的概率分布。 密钥是通过密

    2024年01月17日
    浏览(57)
  • 现代密码学实验五:签名算法

    一、实验目的 1.掌握数字签名的基本原理,理解RSA算法如何提供数字签名。 2.熟悉实验环境和加密软件CrypTool 1.4(CrypTool 2)的使用。 3.编写代码实现签名算法。 二、实验内容 运行CrypTool 1.4(CrypTool 2),使用 RSA 算法对消息进行签名操作,选择公钥PK=(e,N),私钥为sk=(d,N)。例如: 消息

    2024年02月02日
    浏览(49)
  • 第四章 公钥密码 —— 现代密码学(杨波)课后题答案解析

    4. 用推广的Euclid算法求67 mod 119的逆元 解:初始化:(1,0,119), (0,1,67) 1:Q=119/67=1,(0,1,67) , (1,-1,52) 2:Q=67/52=1,(1,-1,52), (-1,2,15) 3:Q=52/15=3,(-1,2,15), (4,-7,7) 4:Q=15/7=2,(4,-7,7), (-9,16,1) 所以67 -1  mod 119=16 10.设通信双方使用RSA加密体制,接收方的公开钥是( e , n )=(5,35),接收到

    2024年02月05日
    浏览(54)
  • 第二章 流密码 —— 现代密码学(杨波)课后题答案解析

    1.3级线性反馈移位寄存器在 c 3 =1时可有4种线性反馈函数,设其初始状态为( a 1 , a 2 , a 3 )=(1,0,1),求各线性反馈函数的输出序列及周期。 解:此时线性反馈函数可表示为 f ( a 1 , a 2 , a 3 )= a 1 Å c 2 a 2 Å c 1 a 3 当 c 1 =0, c 2 =0时, f ( a 1 , a 2 , a 3 )= a 1 Å c 2 a 2 Å c 1 a 3 =

    2024年02月05日
    浏览(50)
  • 【现代密码学基础】详解完美安全与不可区分安全

    目录 一. 介绍 二. 不可区分性试验 三. 不可区分性与完美安全 四. 例题 五. 小结 敌手完美不可区分,英文写做perfect adversarial indistinguishability,其中adversarial经常被省略不写,在密码学的论文中经常被简称为IND安全。 完美不可区分与香农的完美安全是类似的。该定义来源于一

    2024年01月21日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包