在javascript中生成安全密码

时间:2012-09-28 07:37:55

标签: javascript passwords

在javascript中生成安全密码的最快方法是什么?

我希望它包含至少1个特殊字符和2个混合大小写。必须至少6个字符。

6 个答案:

答案 0 :(得分:33)

以下是一些有用的String函数:

String.prototype.pick = function(min, max) {
    var n, chars = '';

    if (typeof max === 'undefined') {
        n = min;
    } else {
        n = min + Math.floor(Math.random() * (max - min + 1));
    }

    for (var i = 0; i < n; i++) {
        chars += this.charAt(Math.floor(Math.random() * this.length));
    }

    return chars;
};


// Credit to @Christoph: http://stackoverflow.com/a/962890/464744
String.prototype.shuffle = function() {
    var array = this.split('');
    var tmp, current, top = array.length;

    if (top) while (--top) {
        current = Math.floor(Math.random() * (top + 1));
        tmp = array[current];
        array[current] = array[top];
        array[top] = tmp;
    }

    return array.join('');
};

您的密码如下所示:

var specials = '!@#$%^&*()_+{}:"<>?\|[];\',./`~';
var lowercase = 'abcdefghijklmnopqrstuvwxyz';
var uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var numbers = '0123456789';

var all = specials + lowercase + uppercase + numbers;

var password = '';
password += specials.pick(1);
password += lowercase.pick(1);
password += uppercase.pick(1);
password += all.pick(3, 10);
password = password.shuffle();

演示:http://jsfiddle.net/Blender/ERCsD/6/

答案 1 :(得分:5)

我现在刚收到帖子。 如果您可以花几分钟时间查看this article,那么使用Math.random()是一个坏主意。

实际上在新版浏览器中有加密API,一旦你开始接触加密,就必须使用它。

这就是为什么我建议使用使用着名的加密API的My library。它适用于服务器端和客户端(nodejs和浏览器)。

MK -

答案 2 :(得分:1)

我修改了@ Blender的答案,使其更安全,也没有改变String.prototype。

// Copy-pasted from:
// https://stackoverflow.com/questions/12635652/generate-a-secure-password-in-javascript
// and modified for Auth0.
//
// Auth0 requirements:
// https://auth0.com/docs/connections/database/password-strength
//
// "at least 10 characters including at least 3 of the following 4 types of characters:
// a lower-case letter, an upper-case letter, a number, a special character (such as !@#$%^&*).
// Not more than 2 identical characters in a row (such as 111 is not allowed)".

const specials = '!@#$%^&*()_+{}:"<>?\|[];\',./`~';
const lowercase = 'abcdefghijklmnopqrstuvwxyz';
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '0123456789';

const all = specials + lowercase + uppercase + numbers;

export default function generatePassword() {
  let password = '';

  password += pick(password, specials, 1, 3);
  password += pick(password, lowercase, 1, 3);
  password += pick(password, uppercase, 1, 3);
  password += pick(password, all, 10);

  return shuffle(password);
}

function pick(exclusions, string, min, max) {
  var n, chars = '';

  if (max === undefined) {
    n = min;
  } else {
    n = min + Math.floor(Math.random() * (max - min + 1));
  }

  var i = 0;
  while (i < n) {
    const character = string.charAt(Math.floor(Math.random() * string.length));
    if (exclusions.indexOf(character) < 0 && chars.indexOf(character) < 0) {
      chars += character;
      i++;
    }
  }

  return chars;
}

// Credit to @Christoph: http://stackoverflow.com/a/962890/464744
function shuffle(string) {
  var array = string.split('');
  var tmp, current, top = array.length;

  if (top) while (--top) {
    current = Math.floor(Math.random() * (top + 1));
    tmp = array[current];
    array[current] = array[top];
    array[top] = tmp;
  }

  return array.join('');
}

答案 3 :(得分:0)

这不是安全的方法。如果仅取决于数学函数(种子),则可以模拟密码生成。如果您尝试将生成与用户事件(如跟踪鼠标位置)相关联(这样可以通过基于用户操作使用不同的种子)将更加安全。

答案 4 :(得分:0)

使用此代码获得强密码:D

const generatePassword = (
  passwordLength = 8,
) => {
  const lowerCase = 'abcdefghijklmnopqrstuvwxyz'
  const upperCase = lowerCase.toUpperCase()
  const numberChars = '0123456789'
  const specialChars = '!"@$%+-_?^&*()'

  let generatedPassword = ''
  let restPassword = ''

  const restLength = passwordLength % 4 
  const usableLength = passwordLength - restLength
  const generateLength = usableLength / 4

  const randomString = (char) => {
    return char[Math.floor(Math.random() * (char.length))]
  }
  for (let i = 0; i <= generateLength - 1; i++) {
    generatedPassword += `${randomString(lowerCase)}${randomString(upperCase)}${randomString(numberChars)}${randomString(specialChars)}`
  }

  for (let i = 0; i <= restLength - 1; i++) {
    restPassword += randomString([...lowerCase, ...upperCase, ...numberChars, ...specialChars])
  }

  return generatedPassword + restPassword
}

答案 5 :(得分:0)

 You could do some thing like below to generate password with following Requirements
    * At least One Special Character
    * At Least on Digit
    * At least on Upper Case
    * At least One Lower Case



function generatePassword(passwordLength) {
      var numberChars = "0123456789";
      var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      var lowerChars = "abcdefghijklmnopqrstuvwxyz";
      var specialChars = "#?!@$%^&*-";
      var allChars = numberChars + upperChars + lowerChars + specialChars;
      var randPasswordArray = Array(passwordLength);
      randPasswordArray[0] = numberChars;
      randPasswordArray[1] = upperChars;
      randPasswordArray[2] = lowerChars;
      randPasswordArray[3] = specialChars;
      randPasswordArray = randPasswordArray.fill(allChars, 4);
      return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(Math.random() * x.length)] })).join('');
    }
    
    function shuffleArray(array) {
      for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
      }
      return array;
    }
    
    //Change length accordingly
    alert(generatePassword(12));