我打算使用哈希生成验证令牌来验证电子邮件地址。哈希将像这样生成:
email:username:salt
哈希是使用 SHA256 算法生成的,并且每个生成的令牌都使用相同的盐。
另一种更常用的方法是生成一次性 UID,该 UID 存储在数据库中并用作新电子邮件地址的验证。
我的问题是:这是实现生成电子邮件验证令牌的有效方法(考虑处理器和磁盘利用率等)。
我打算使用哈希生成验证令牌来验证电子邮件地址。哈希将像这样生成:
email:username:salt
哈希是使用 SHA256 算法生成的,并且每个生成的令牌都使用相同的盐。
另一种更常用的方法是生成一次性 UID,该 UID 存储在数据库中并用作新电子邮件地址的验证。
我的问题是:这是实现生成电子邮件验证令牌的有效方法(考虑处理器和磁盘利用率等)。
电子邮件验证令牌的全部目的是从您的安全 Web 服务器生成一个令牌,并将该令牌通过电子邮件发送给某人,以便他们可以单击包含该令牌的链接,然后您就可以验证他们的帐户。
要记住的重要事项:
因此,我不推荐您采用的方法。
相反,我会使用JSON Web 令牌(这对他们来说是一个理想的用例)。This other SO question有一个不错的总结。
使用 JWT 可以让您:
当用户将令牌发送回您的 Web 服务器时,JWT 将:
我希望这会有所帮助=)
你正在做的事情有点安全。
我会将您的盐称为键-您正在生成键控哈希。确保生成具有足够熵的密钥。我会推荐由 CSPRNG 生成的 128 位的强度。
以这种方式生成的一些键控散列容易受到长度扩展攻击。也就是说,如果攻击者生成了一个验证令牌,foo@example.com
那么他们将能够计算出foo@example.com.example.org
. 这是因为哈希算法的输出也背叛了它的状态。为了缓解这种情况,您可以使用HMAC 算法。
您当前的方法还存在电子邮件地址始终具有相同令牌的限制。如果电子邮件地址过期(例如 Bob Smithbobs@example.org
在示例组织的工作中被解雇,他将知道下一个 Bob S. 在开始为示例组织工作时将获得的验证码)。这是否对您的申请有任何风险由您决定。为了缓解这种情况,您可以改用JWT,这将使您能够将到期日期放入可以验证的令牌中。JWT 的 HS256 算法也使用了 HMAC,也解决了这个问题。
使用键控散列应该是高效的,并且没有数据库查找的存储、维护和开销。
您所说的 UID 是指UUID吗?
请记住:
[UUID] 的目的是全局唯一,而不是不可猜测。
和
[UUID] 是为唯一性而非安全性而设计的。
您最好使用安全的熵源(比如另一个 CSPRNG)动态生成 128 位令牌。您可能希望使用 SHA-256 在服务器端对这些(不加盐)进行哈希处理,以防止任何数据泄漏漏洞意味着攻击者可以验证任何电子邮件地址。