web-dev-qa-db-ja.com

LastPassのパスワードジェネレーターのセキュリティ

現在、パスワードの生成と管理にはすべてLastPassを使用しています。 Diceware を読んだ後、LastPassのパスワードジェネレーターは安全ではない可能性があることに気付きました。

私は彼らのコードをこのWebサイトに投稿することに慎重ですが、彼らのコードを検査したところ、 ここ で、各文字について、文字タイプ(上、下、数字、記号、またはAll)、次に、事前定義されたリストからランダムな文字を選択します。

私は彼らの乱数生成コードを見ようとしました、そして彼らは時間を種として使用しているようです。私はrng_poolがどこから来たのか、それがパスワードを生成するためにどのように機能するのか完全にはわかりません。

彼らはどの生成方法を使用しており、安全ですか?

(ページの重要な関数はlpCreatePassgetRandomです)

15
Nathan Merrill

RNGに window.crypto をシードしているように見える場合、使用できない場合は 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暗号化API の一部です:

[Web Cryptography API]仕様では、ハッシュ、署名の生成と検証、暗号化と復号化など、Webアプリケーションで基本的な暗号化操作を実行するためのJavaScript APIについて説明しています。さらに、アプリケーションがこれらの操作を実行するために必要なキー情報を生成および/または管理するためのAPIについても説明します。このAPIの用途は、ユーザーまたはサービスの認証、ドキュメントまたはコードの署名、通信の機密性と整合性にまで及びます。

window.msCryptoは、これをMicrosoftが実装したものです。

サポートされているブラウザーを使用している場合、この生成方法は安全に見えます(ブラウザーのWeb暗号化APIの実装と同じくらい安全です)。そうでない場合は、Math.randomセキュアではない現在時刻がシードされています-これが当てはまる場合は、Webページから警告が出されるとよいでしょう。

このページには、 Web暗号化API のブラウザーサポートの現在のステータスが表示されます。

15
SilverlightFox