PFS & wPFS

Forward secrecy

HMQV: A High-Performance Secure Diffie-Hellman Protocol

Session-Key Generation using Human Passwords Only

PFS (perfect forward secrecy) 指即使long term key泄漏,也不会影响之前的session key

wPFS (weak perfect forward secrecy) 指即使long term key泄漏,也不会影响之前passive attacker监听下的session key(但是 actively interfered attacker的session key可能受影响)

PAKE

pake selection

Password Authenticated Key Exchange (PAKE) protocols 指的是通信双方基于共享的password安全生成session key。

balanced PAKE是指通信双方保存相同的password,augumented PAKE是指其中一方保存password的变换值。

RFC8125: Requirements for Password-Authenticated Key Agreement (PAKE) Schemes

把PAKE的菜名报了一遍。

公钥的传输方式

Encrypted Key Exchange(EKE):以Password派生的kek,加密ephemeral public key

J-PAKE:交换ephemeral public key,以及基于password派生的value

Strong Password-Only Authenticated Key Exchange (SPEKE):基于Password派生generator,交换派生的public key

PACE:加密传输nonce,以nonce派生common base。

是否多人参与

Group PAKEs

安全性

尤其是对dictionary attack的抗性

用途

基于password做key distribution

是否整合long term public key

用户标识的隐私保护可考虑数字信封

balanced PAKE

CPace

cpace

复用hash_to_curve的映射,基于PRS和相关参数,在选定的曲线上映射到某个生成元G: G.calculate_generator(H,PRS,CI,sid)

  • H: hash_to_field的hash算法
  • PRS: 为password的派生值、或者password本身
  • CI: channel标识
  • sid: session标识

A/B双方各自生成一个1 ~ n-1的随机数ya/yb,对应的Point为Ya = G * ya, Yb = G * Yb A/B各自的身份标识为ADa/ADb A/B互相交换[Ya, ADa], [Yb, ADb]

A/B结合所交换的信息,各自派生ISK

  • K = G.scalar_mult_vfy(yb,Ya) = G.scalar_mult_vfy(ya, Yb)
  • order 如果A/B按initiator/responder的顺序交互信息:ISK = H.hash(prefix_free_cat(G.DSI || "_ISK", sid, K)||MSGa || MSGb)
  • unorder 如果 A/B 并行交互信息:ISK = H.hash(prefix_free_cat(G.DSI || "_ISK", sid, K)||ocat(MSGa, MSGb)) ,其中ocat是对MSGa/MSGb做排序后的拼接。
  • 显然,派生参数包含了双方所有交互信息

cpace整个协议流比较简洁,漂亮。

Dragony,RFC7664

把pw通过指定的F函数,映射为ECC上的一个点: F(pw), 文档里记为PE

PE做为下面计算的基点

通信双方各自随机选两个整数,一个private, 一个mask

A -> B :   private_a + mask_a,  - mask_a * PE
B -> A :   private_b + mask_b,  - mask_b * PE

显然,最终双方能获得 private_a*private_b*PE
然后再派生出kck = key confirm key,mk = master key

PS: 这个RFC不好读,主要原因是,它把椭圆曲线的加法和乘法又重新用函数表述了一下

用例:TLS-PWD, RFC8492、WIFI WPA3

SPAKE2

Simple Password-Based Encrypted Key Exchange Protocols 的SPAKE2是 2-message 交互,通过M,N的password幂计算协作完成类DH交换,wPFS

Forward Secrecy of SPAKE2 的PFS-SPAKE2是 3-message 交互,通过M的password幂计算协作完成类DH交换,加入了两个中间的hash确认码,PFS

通信双方已知基点P,以及另外两个点M & N,且分别选取一个随机数x

    A -> B : x_a * P + pw * M
    B -> A : x_b * P + pw * N
    显然,最终双方能获得 x_a*x_b*P

SESPAKE, RFC8133

通信双方已知基点P,基于P以指定的函数派生{ Q_1, ..., Q_N },且分别选取一个随机数x

B -> A : 随机的ind、salt
A 计算 : Q_PW = int(F(PW, salt, 2000))*Q_ind
A -> B : u_1 = x_a*P - Q_PW
B -> A : u_2 = x_b*P + Q_PW
显然,最终双方能获得 x_a*x_b*P

如果B是服务端,那么可以存储{ ind, salt, Q_PW },避免明文存储PW再实时计算Q_PW => 此时,则为augumented模式。

J-PAKE, RFC8236

augumented PAKE

SPAKE2+

通信双方已知基点P,以及另外两个点M & N,且分别选取一个随机数x

(w_0, w_1) = KDF(pw)   // A已知pw,B仅存储w_0、w_1*P

    A -> B : x_a * P + w_0 * M
    B -> A : x_b * P + w_0 * N
    显然,最终双方能获得 SK_0 = x_a*x_b*P, SK_1 = w_1*x_b*P

OPAQUE

OPAQUE: An Asymmetric PAKE ProtocolSecure Against Pre-Computation Attacks

OPAQUE比较绕

服务端S生成公私钥对 { Priv_U, Pub_U }, { Priv_S, Pub_S }

S随机生成K_s
客户端U与服务端S会计算共享密钥:RW=OPRF(K_s, pw) =H(pw,(H'(pw))^K_s)

注意,这里S不会把K_s明文传给U,而是通过 

    U随机生成r, x_u
    U -> S: a = H'(pw)^ r , X_u = g^x_u
    S -> U: b = a^K_s
    显然,最终U与S能获得RW

S使用RW封装c = AuthEnc_rw({ Priv_U, Pub_U, Pub_S })
S为U保存 { K_s, Priv_S, Pub_S, Pub_U, c }

S生成随机数x_s,以及对应的公钥X_s
S计算K = KE(Priv_S, x_s, Pub_U, X_u),   ssid' = H(sid, ssid, a), SK = f_K(0, ssid'), A_s = f_K(1, ssid'), A_u = f_K(2, ssid')
S -> U : b, X_s, c, A_s

U解密c,获得Priv_U, Pub_U, Pub_S
U计算 K=KE(Priv_U, x_u, Pub_S, X_s),同样计算ssid', SK, A_s, A_u

其中KE为HMQV计算:
S: KE = H((X_u * Pub_U^e_u)^(x_s + e_s*Priv_S))
U: KE = H((X_s * Pub_S^e_s)^(x_u + e_u*Priv_U))
e_u = H(X_u, S, ssid'), e_s = H(X_s, U, ssid')

SRP, RFC2945

A Comparison of the Password-Authenticated Key Exchange Protocols, SRP-6a and PAKE2+

SRP-6a

k是双方都知道的整数值

U : salt = s,  x = hash(pwd, s),  v = g^x
S记录了与U关联的salt = s, v

U生成随机数a
U -> S:  A = g^a,  Username

S根据Username取出对应的s, v
S生成随机数b
S计算: B = k*v + g^b
        u = hash(A, B)
        S = ( A * v^u )^b
        K = hash(S)
S -> U : s, B

U计算: u = hash(A, B)
        x = hash(pwd, s)
        S = ( B - k*g^x )^(a + u*x)
          = ( k*v + g^b - k*v )^(a + u*x)
          = g^(b * (a + u*x))
          =  (g^a * g^(x*u) )^b
          =  (A * v^u)^b
        K = hash(S)
        M1 = hash(A, B, K)


Published

06 November 2019

Tags


Share On