Mega 用户认证加密系统
文件下载
https://assets.lacus.site/Document/SecurityWhitepaper.pdf
TODO
- Method to Protect Passwords in Databases for Web Applications
注册过程
密码评分
密码使用 ZXCVBN password strength estimator library (v4.4.2)
, 进行密码评分,评分结果在0-4之间
密码至少需要有八位,因为即使过短的密码也可能获取到1的评分
针对评分需要给用户合适的提醒
Length < 8 Too short
Score 0 and Length >= 8 Too weak
Score 1 and Length >= 8 Weak
Score 2 and Length >= 8 Medium
Score 3 and Length >= 8 Good
Score 4 and Length >= 8 Strong
密码处理
Password Processing Function (PPF), Mega使用了PBKDF2
PBKDF2简单而言就是将salted hash进行多次重复计算 ———— 百度
首先随机生成一个128位(16字节)的随机主密钥 Master Key
,Web可以使用Crypto.getRandomValues()
同时也生成一个128位的(16字节) 的客户端随机值 Client Random Value
使用上边两个随机数做散列得到盐
值
Salt = SHA_256(`mega.nz${padding}${ClientRandomValue}`)
padding: Mega用的是大写的P
,使得mega.nz${padding}
整体的长度为200字符,以避免计时攻击
正常推荐在计算盐的时候要带上用户标识符,例如用户邮件,但是对于Mega来讲,用户可能会修改邮件,导致需要重新计算盐值和主密钥
Mega推荐的PPF迭代次数为100,000次
生成一个256位(32字节)的派生密钥 Derived Key
Derived_Key = PBKDF2_HMAC_SHA_512(Password, Salt, Iteration || 100000, Length || 256)
拆分这个256位的派生密钥,前半部分为派生加密密钥 Derived Encryption Key
, 后半部分为派生验证密钥 Derived Authentication Key
,在发送更敏感的数据之前(如加密密钥、会话ID)
然后用派生加密密钥加密主密钥,生成加密主密钥 Encrypted Master Key
Encrypted_Master_Key = AES_ECB(Derived_Encryption_Key , Master_Key)
使用派生验证密钥做散列得到哈希认证密钥 Hashed Authentication Key
Hashed_Authentication_Key = SHA_256(Derived_Authentication_Key)
完成以上操作后,客户端会将邮件 Email
、客户端随机值 Client Random Value
、加密主密钥 Encrypted Master Key
、哈希认证密钥 Hashed Authentication Key
发送给服务器
登录过程
输入邮件
将邮件发送给服务器,如果邮件存在则会返回该邮件对应的盐值 Salt
Salt = SHA_256(`mega.nz${padding}${ClientRandomValue}`)
如果邮件不存在则返回一个假的盐值盐值 Salt
Salt = SHA_256(`${Email}mega.nz${padding}${ServerRandomValue}`)
padding: Mega用的是大写的P
,使得${Email}mega.nz${padding}
整体的长度为200字符,以避免计时攻击
邮件最大的长度是190字符,否则将被服务器拒绝,避免无用的攻击
ServerRandomValue
服务器随机值是固定存储在服务器的一串128位长度的字符串
输入密码
客户端可以使用服务器返回的盐值计算一个256位(32字节)的派生密钥 Derived Key
Derived_Key = PBKDF2_HMAC_SHA_512(Password, Salt, Iteration || 100000, Length || 256)
将派生密钥的后半部分作为派生验证密钥 Derived Authentication Key
连同邮件一起发送给服务器
服务将使用派生验证密钥做散列得到哈希认证密钥 Hashed Authentication Key
Hashed_Authentication_Key = SHA_256(Derived_Authentication_Key)
将计算结果与数据库中的密钥进行比对,如果匹配则认为是成功的身份验证,返回加密主密钥 Encrypted Master Key
,以及加密的RSA私钥 Encrypted Private RSA Key
和加密的会话标识符 Encrypted Session ID
如果不匹配则拒绝该请求
数据库不存储未经加密的认证密钥,只存储哈希认证密钥,防止哈希传递
攻击(其中,在数据库泄露的场景中,攻击者只传递哈希认证密钥,以获得身份验证,并作为真实用户执行操作)
服务器总是哈希从客户端收到的认证密钥,以防止这种攻击向量
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!