零知识证明-SRP协议简介SRP是SecureRemotePassword协议的缩写,是一种密码协议,用于在客户端和服务器之间建立安全的身份验证。该协议的设计旨在避免将用户密码明文传输到服务器,从而提高了安全性。
SRP 是 Secure Remote Password 协议的缩写,是一种密码协议,用于在客户端和服务器之间建立安全的身份验证。该协议的设计旨在避免将用户密码明文传输到服务器,从而提高了安全性。
在 SRP 协议中,客户端和服务器之间的身份验证是通过一个互相协商的共享会话加密密钥进行的,而该密钥是基于用户的密码和随机数生成的。这个过程涉及到数学计算和密码学。因此,即使传输过程中被截获,攻击者也无法获取用户的密码。
这是一个零知识证明协议,服务器不需要存储密码等价信息(散列版本),客户可以安全地对服务器进行认证。而窃听者或中间人无法获得任何有意义的信息来进行攻击。SRP提供了很大的好处,例如。
该流程模拟了一个用户通过浏览器或者其他终端与服务端进行通信,该流程主要分为两部分:
注册
生成共享会话加密密钥
验证
Salt:随机字符串
KDF:一种密钥派生函数,将密码转换为非常大的数字,例如: PBKDF等。
SRP组:由一个大质数组成的一个生成器。您可以在几个组之间进行选择,例如: 1024位,2048位等,在客户端和验证端可以事先约定使用几位的组。
verifier:这是从x生成的随机字符串,它不是密码的散列版本,也不能有效地用来猜测密码。
// ┌──────────────┐ ┌──────────────┐
// │ Browser │ │ Web Server │
// └──────────────┘ └──────┬───────┘
// │
// │
// .─. ┌─┴─┐ GET /register.html ┌───┐
// ( ) │ │◀────────────────────────────────│ │
// `┬' │ │ └───┘
// ────┼──── │ │ │
// │ email,passwd │ │
// ┌┴┐ ─────────────▶ ├──┐ │
// │ │ │ │ │ generateSalt()
// │ │ │ │ │ generateVerifier(email,passwd) │
// ──┘ └── │ │◀─┘
// │ │ │
// │ │
// │ │ │
// │ │ POST {email,salt,verifier} ┌───┐
// │ ├────────────────────────────────▶│ │
// │ │ └───┘
// └───┘ │
// │
客户端
客户端向服务器发出请求,以获得给定用户名的salt和SRP组。
把用户名、密码、salt当做参数传递给KDF以得出x(与注册时相同)。
使用SRP组生成一个一次性的短暂值a(私有)和它的对应值A(公有),私有的a被保存在内存中,它的公有值A被发送到服务器上。
服务端
此时,一个拥有(x,a,B)的客户和拥有(verifier,b,A)的服务器使用不同的计算方法可以得出相同的值,其被用作会话加密密钥。
// ┌──────────────┐ ┌──────────────┐
// │ Browser │ │ Web Server │
// └──────────────┘ └──────────────┘
// │ │
// .─. ┌───┐ GET /login.html ┌───┐
// ( ) email,passwd │ │◀────────────────────────────────│ │
// `┬' ─────────────▶│ │ └───┘ .───────────.
// ────┼──── │ │ AJAX /challenge {email} │ ( Database )
// │ │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▶───┐ (`───────────')
// ┌┴┐ │ │ ┌─┤ │◀──────────────(`───────────')
// │ │ │ │ step1(email,salt,verifier)│ │ │{salt,verifier}(`───────────')
// │ │ │ │ │ │ │ `───────────'
// ──┘ └── │ │ └▶│ │
// │ │ {salt,B} │ │ store b .───────────.
// ┌─┤ │◀─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ ├──────────────▶( Cache )
// step1(email,passwd)│ │ │ └─┬─┘ (`───────────')
// step2(salt,B)│ │ │ POST /auth {email,A,M1} ┌───┐ load b (`───────────')
// └▶│ ├─────────────────────────────────│ │◀──────────────(`───────────')
// └───┘ ┌─┤ │ `───────────'
// │ step2(A,M1)│ │ │ ┌───────────────────┐
// │ │ │ │You have to retain │
// ┌─┴─┐ {M2} └▶│ │ │the private "b" │
// step3(M2)│ │◀────────────────────────────────┤ │ │which matches the │
// └─┬─┘ REDIRECT /home.html OR └─┬─┘ │public challenge │
// ┌──────────────────────┐ /login.html │"B". This can be in│
// │step3 confirms a │ │ │ │the main DB or a │
// │shared private key. A │ │cache. │
// │mobile running │ │ │ └───────────────────┘
// │embedded JavaScript │ ▼ ▼
// │also confirms the │
// │server knows the │
// │verifier that the user│
// │registered with. │
// └──────────────────────┘
在上一步中,我们只是在客户端和服务端创建了相同的会话加密密钥,而没有交换任何敏感信息,但我们没有验证双方是否导出了相同的值。所以这里介绍一下验证流程,如下所示:
参考链接: https://medium.com/swlh/what-is-secure-remote-password-srp-protocol-and-how-to-use-it-70e415b94a76
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!