我有一个简单算法的非常基本的想法,允许用户通过请求发送到他们的电子邮件的随机代码来重置他们的密码。
如果用户忘记了他们的 PW,他们可以请求服务器生成重置代码并将其作为电子邮件发送给他们。然后将此代码附加到他们在数据库中的用户条目。确认输入表单将要求用户在前端键入重置代码 - 如果他们失败,代码将被标记并失效。如果他们成功了,他们将被发送到一个新的 PW 重置表单,他们可以在其中更新他们的凭据以通过向后端发送 PUT
请求来替换。
这是我的基本想法-
function generate7KeyPasswordResetConfirmationCode() {
const arrayOfSeven = [1, 2, 3, 4, 5, 6, 7]
const alphabet = [Array of 26 Lowercase Chars and 26 Uppercase Chars]
const letterOrNumber = arrayOfSeven.map(currentPos => {
// return pseudorandom number between 0-100
const oneToOneHundred = Math.floor(Math.random() * Math.floor(101))
if (oneToOneHundred < 50) { return "char" }
else if (oneToOneHundred >= 50) { return "num" }
})
const resetKey = letterOrNumber.map(numOrChar => {
// return pseudorandom number between 0-51 and return a-z-A-Z
if (numOrChar === "char") {
const index = Math.floor(Math.random() * Math.floor(52))
return alphabet[index]
}
// return pseudorandom number 0-9
if(numOrChar === "num") {
return Math.floor(Math.random() * Math.floor(10))
}
})
return resetKey
}
但是,我的方法涉及Math.random(),我在MDN上注意到了这个东西:
Math.random() 不提供加密安全随机数。不要将它们用于与安全相关的任何事情。请改用 Web Crypto API,更准确地说是 window.crypto.getRandomValues() 方法
我知道我可以只使用 uuid4,但我想创建我自己的解决方案 - 如何破解它?如果我在第一次尝试失败时使代码无效,还有什么可能出错?
最佳答案
不,使用不安全的随机数生成器绝不是个好主意。随机生成的密码应具有与随机生成的 key 相似的属性。无法保证随机数生成器不会受到其他脚本的影响。在最坏的情况下,其他脚本可以找出随机数生成器的状态并直接计算您的密码。
所以请使用window.crypto.getRandomValues(array)
生成密码。可以找到从安全 随机数生成器检索密码的无偏实现 here .
如果您无法访问随机数生成器,则:
- 从服务器获取一个安全的随机数;
- 添加来自客户端的随机熵(鼠标移动、系统时间、一些不安全的随机值等),并将它们连接到来自服务器的随机数;
- 对生成的数组执行安全计算,例如哈希或 PRNG 实现,以创建随机数;
- 使用 (3) 创建密码。
您绝对应该只通过安全连接执行此操作,并牢记网络钓鱼攻击。
关于javascript - 可以使用 Math.random() 生成密码重置 key 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48849582/