从哈希派生强密码

时间:2016-08-29 04:26:39

标签: javascript passwords password-protection

我正在加密,希望避免犯错。我已经阅读了很多关于确定性密码生成的内容。我有一个我觉得很舒服的方案。寻求其中一个组件的帮助。

首先,我计划使用scrypt作为主密码。我还有其他独特的输入,将与scrypt输出结合使用,以创建最终的密码派生。我在这里专注于如何遵守不同的密码要求方案的问题。下面是一个可以在jsfiddle中运行的函数。它应输出生成的密码和匹配要求所需的迭代次数。我可以为密码方案,输入参数和所需的迭代次数存储3元组字符要求。我希望这很强大,可以避免伤害。我不确定如何通过典型的十六进制哈希转换生成大写字母和特殊字符,下面是我认为有效,但我不确定它可能受到什么样的攻击。<​​/ p>

  • 评论填充似乎会产生一些问题?
  • 转换为八进制是否有任何问题(我是否会丢失随机性?)然后转换为char?

示例代码

var input_secret = "e"
var max_it = 1000
var special_chars = 10
var digit_chars = 6
var cap_chars = 4

function hex2a(hexx) {
    var hex = hexx.toString();//force conversion
    var str = '';
    for (var i = 0; i < hex.length; i += 2){
      str += //String.fromCharCode(parseInt(hex.substr(i, 2), 16));
      String.fromCodePoint(parseInt(hex.substr(i, 2), 16));
    }
    return str;
}

function sha256(str, it) {
  if (it > max_it){
    throw new Error("can't find a match to satisfy regex");
  }
  console.log("iteration: ",it)
  // We transform the string into an arraybuffer.
  var buffer = new TextEncoder("utf-8").encode(str);
  return crypto.subtle.digest("SHA-256", buffer).then(function (hash) {
    var t = hex(hash)
    if (!reg.test(t) && it < max_it){
        console.log("failed requirements",t)
      var new_it = it + 1
      return sha256(t,new_it)
    } else if(it >= max_it){
        console.log("HORROR")
        return false      
    }
    else{
      return [t,it]
    }

  });
}

var reg_string = '(?=(.*(\\`|\\~|\\!|\\@|\\#|\\$|\\%|\\^\|\\*|\\(|\\|\\-)){'+special_chars+'})(?=(.*\\d){'+digit_chars+'})(?=.*[a-z])(?=(.*[A-Z]){'+cap_chars+'}).{14,14}'

var reg = new RegExp(reg_string)
console.log("regexp",reg)

function hex(buffer) {
  var hexCodes = [];
  var view = new DataView(buffer);
  for (var i = 0; i < view.byteLength; i += 4) {
    // Using getUint32 reduces the number of iterations needed (we process 4 bytes each time)
    var value = view.getUint32(i)
    // toString(16) will give the hex representation of the number without padding
    var stringValue = value.toString(8)

    // We use concatenation and slice for padding
    //var padding = '00000000'
    var padding = ''
    var paddedValue = (padding + hex2a(stringValue)).slice(-padding.length)
    hexCodes.push(paddedValue);
  }

  // Join all the hex strings into one
  return hexCodes.join("");
}



console.log("Input 'e' should take 454 iterations to satisfy 10 special, 6 digits, and 4 caps");
sha256(input_secret,1).then(function(res) {
    var digest = res[0]
  var iterations = res[1]
  var printable_digest = digest.replace(/[^\x20-\x7E]+/g, '');
console.log([[special_chars,digit_chars,cap_chars],printable_digest,iterations]);
  console.log("test",reg.test(printable_digest))
});

0 个答案:

没有答案