LastPass 密码生成器的安全性

信息安全 密码 最后一次
2021-09-02 05:33:38

我目前使用 LastPass 来生成和管理所有密码。阅读Diceware 后,我意识到 LastPass 的密码生成器可能不安全,因为有人可能会尝试生成与我相同的密码。

我对在这个网站上发布他们的代码持谨慎态度,但是通过在这里检查他们的代码,我看到他们为每个字符选择一个字符类型(大写、小写、数字、符号或全部),然后选择一个预定义列表中的随机字符。

我试图查看他们的随机数生成代码,看起来他们使用时间作为种子。我不完全确定 rng_pool 来自哪里,以及它是如何生成密码的。

他们使用什么生成方法,它是否安全?

(页面上的重要功能是lpCreatePassgetRandom

1个回答

如果似乎使用window.crypto为 RNG 播种,如果不可用,则使用window.msCrypto并最终回退到当前时间。相关代码为:

var rng_state;
var rng_pool;
var rng_pptr;


// Mix in a 32-bit integer into the pool
function rng_seed_int(x) {
  rng_pool[rng_pptr++] ^= x & 255;
  rng_pool[rng_pptr++] ^= (x >> 8) & 255;
  rng_pool[rng_pptr++] ^= (x >> 16) & 255;
  rng_pool[rng_pptr++] ^= (x >> 24) & 255;
  if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
}

// Mix in the current time (w/milliseconds) into the pool
function rng_seed_time() {
  rng_seed_int(new Date().getTime());
}

// Initialize the pool with junk if needed.
if(rng_pool == null) {
  rng_pool = new Array();
  rng_pptr = 0;
  var t;
  if(typeof(navigator) != 'undefined' && navigator.appName == "Netscape" && navigator.appVersion < "5" && typeof(window) != 'undefined' && window.crypto) {
    // Extract entropy (256 bits) from NS4 RNG if available
    var z = window.crypto.random(32);
    for(t = 0; t < z.length; ++t)
      rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
  }  

  //First try to use browser's PRNG over Math.random
  try{
    var crypt_obj = null;
    if (typeof(window) != "undefined" && typeof(window.crypto) != "undefined") {
      crypt_obj = window.crypto;
    } else if (typeof(window) != "undefined" && typeof(window.msCrypto) != "undefined") {
      crypt_obj = window.msCrypto;
    }



 if(typeof(crypt_obj) != 'undefined' && typeof(crypt_obj.getRandomValues) == 'function') {
      if(rng_pptr < rng_psize){
        var num = Math.floor((rng_psize - rng_pptr) / 2) + 1;
        var buf = new Uint16Array(num);
        crypt_obj.getRandomValues(buf);
        for(var i = 0; i < buf.length; i++){
          var t = buf[i];
          rng_pool[rng_pptr++] = t >>> 8;
          rng_pool[rng_pptr++] = t & 255;
        }
      }
    }
  }catch(e){}

  //Fall back to Math.random if needed
  while(rng_pptr < rng_psize) {  // extract some randomness from Math.random()
    t = Math.floor(65536 * Math.random());
    rng_pool[rng_pptr++] = t >>> 8;
    rng_pool[rng_pptr++] = t & 255;
  }
  rng_pptr = 0;
  rng_seed_time();
  //rng_seed_int(window.screenX);
  //rng_seed_int(window.screenY);
}

Window.crptoWeb Cryptography API的一部分:

[Web Cryptography API] 规范描述了一种 JavaScript API,用于在 Web 应用程序中执行基本的加密操作,例如散列、签名生成和验证以及加密和解密。此外,它还描述了一个 API,供应用程序生成和/或管理执行这些操作所需的密钥材料。此 API 的用途包括用户或服务身份验证、文档或代码签名以及通信的机密性和完整性。

window.msCrypto 是微软对此的实现。

如果您使用受支持的浏览器,则此生成方法看起来是安全的(它与您的浏览器的 Web Cryptography API 实现一样安全)。如果不是,那么它似乎使用Math.random不安全的当前时间播种 - 如果是这种情况,如果网页警告您会很好。

此页面显示浏览器对 Web Cryptography API 的支持当前状态