Показать сообщение отдельно
  #2 (permalink)  
Старый 07.02.2019, 12:43
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

$ yarn init
$ yarn add @trust/webcrypto
$ touch securerandom.js
$ touch index.js

securerandom.js
/*!
* Random number generator with ArcFour PRNG
* 
* NOTE: For best results, put code like
* <body onclick='SecureRandom.seedTime();' onkeypress='SecureRandom.seedTime();'>
* in your main HTML document.
* 
*/
// Constructor function of Global SecureRandom object
const _crypto = require('crypto');
const crypto = require('@trust/webcrypto')
let sr = function () { };

// Properties
sr.state;
sr.pool;
sr.pptr;
sr.poolCopyOnInit;

// Pool size must be a multiple of 4 and greater than 32.
// An array of bytes the size of the pool will be passed to init()
sr.poolSize = 256;

// --- object methods ---

// public method
// ba: byte array
sr.prototype.nextBytes = function (ba) {
  var i;
  // if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
  try {
    var rvBytes = new Uint8Array(ba.length);
    // window.crypto.getRandomValues(rvBytes);
    crypto.getRandomValues(rvBytes);
    for (i = 0; i < ba.length; ++i)
      ba[i] = sr.getByte() ^ rvBytes[i];
    return;
  } catch (e) {
    // alert(e);
    console.log(e)
  }
  // }
  for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte();
};


// --- static methods ---

// Mix in the current time (w/milliseconds) into the pool
// NOTE: this method should be called from body click/keypress event handlers to increase entropy
sr.seedTime = function () {
  sr.seedInt(new Date().getTime());
}

sr.getByte = function () {
  if (sr.state == null) {
    sr.seedTime();
    sr.state = sr.ArcFour(); // Plug in your RNG constructor here
    sr.state.init(sr.pool);
    sr.poolCopyOnInit = [];
    for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr)
      sr.poolCopyOnInit[sr.pptr] = sr.pool[sr.pptr];
    sr.pptr = 0;
  }
  // TODO: allow reseeding after first request
  return sr.state.next();
}

// Mix in a 32-bit integer into the pool
sr.seedInt = function (x) {
  sr.seedInt8(x);
  sr.seedInt8((x >> 8));
  sr.seedInt8((x >> 16));
  sr.seedInt8((x >> 24));
}

// Mix in a 16-bit integer into the pool
sr.seedInt16 = function (x) {
  sr.seedInt8(x);
  sr.seedInt8((x >> 8));
}

// Mix in a 8-bit integer into the pool
sr.seedInt8 = function (x) {
  sr.pool[sr.pptr++] ^= x & 255;
  if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize;
}

// Arcfour is a PRNG
sr.ArcFour = function () {
  function Arcfour() {
    this.i = 0;
    this.j = 0;
    this.S = new Array();
  }

  // Initialize arcfour context from key, an array of ints, each from [0..255]
  function ARC4init(key) {
    var i, j, t;
    for (i = 0; i < 256; ++i)
      this.S[i] = i;
    j = 0;
    for (i = 0; i < 256; ++i) {
      j = (j + this.S[i] + key[i % key.length]) & 255;
      t = this.S[i];
      this.S[i] = this.S[j];
      this.S[j] = t;
    }
    this.i = 0;
    this.j = 0;
  }

  function ARC4next() {
    var t;
    this.i = (this.i + 1) & 255;
    this.j = (this.j + this.S[this.i]) & 255;
    t = this.S[this.i];
    this.S[this.i] = this.S[this.j];
    this.S[this.j] = t;
    return this.S[(t + this.S[this.i]) & 255];
  }

  Arcfour.prototype.init = ARC4init;
  Arcfour.prototype.next = ARC4next;

  return new Arcfour();
};


// Initialize the pool with junk if needed.
if (sr.pool == null) {
  sr.pool = new Array();
  sr.pptr = 0;
  var t;
  // if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
  try {
    // Use webcrypto if available
    var ua = new Uint8Array(sr.poolSize);
    // window.crypto.getRandomValues(ua);
    crypto.getRandomValues(ua);
    for (t = 0; t < sr.poolSize; ++t)
      sr.pool[sr.pptr++] = ua[t];
  } catch (e) {
    console.log(e)
    //  alert(e); 
  }
  // }
  while (sr.pptr < sr.poolSize) {  // extract some randomness from Math.random()
    t = Math.floor(65536 * Math.random());
    sr.pool[sr.pptr++] = t >>> 8;
    sr.pool[sr.pptr++] = t & 255;
  }
  sr.pptr = Math.floor(sr.poolSize * Math.random());
  sr.seedTime();
  // entropy
  var entropyStr = "";
  // screen size and color depth: ~4.8 to ~5.4 bits
  entropyStr += Math.random() * 2345
  entropyStr += Math.random() * 3456
  // entropyStr += (window.screen.height * window.screen.width * window.screen.colorDepth);
  // entropyStr += (window.screen.availHeight * window.screen.availWidth * window.screen.pixelDepth);
  // // time zone offset: ~4 bits
  var dateObj = new Date();
  var timeZoneOffset = dateObj.getTimezoneOffset();
  entropyStr += timeZoneOffset;
  entropyStr += Math.random() * 3456
  entropyStr += Math.random() * 3456
  entropyStr += Math.random() * 3456
  entropyStr += Math.random() * 3456


  // // user agent: ~8.3 to ~11.6 bits
  // entropyStr += navigator.userAgent;
  // // browser plugin details: ~16.2 to ~21.8 bits
  // var pluginsStr = "";
  // for (var i = 0; i < navigator.plugins.length; i++) {
  //   pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", ";
  // }
  // var mimeTypesStr = "";
  // for (var i = 0; i < navigator.mimeTypes.length; i++) {
  //   mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", ";
  // }
  // entropyStr += pluginsStr + mimeTypesStr;
  // // cookies and storage: 1 bit
  // entropyStr += navigator.cookieEnabled + typeof (sessionStorage) + typeof (localStorage);
  // // language: ~7 bit
  // entropyStr += navigator.language;
  // // history: ~2 bit
  // entropyStr += window.history.length;
  // // location
  // entropyStr += window.location;

  // let hash = crypto.createHash('sha256')
  // hash.update(data)
  // result = hash.digest()

  // var entropyBytes = Crypto.SHA256(entropyStr, { asBytes: true });
  var entropyBytes = _crypto.createHash('sha256').update(entropyStr).digest()
  console.log(entropyBytes)
  for (var i = 0; i < entropyBytes.length; i++) {
    sr.seedInt8(parseInt(entropyBytes[i], 10));
  }
}

module.exports = sr


index.js
let sr = require('./securerandom')
sr.seedTime()
console.log(sr.pptr)


только я закомментил строки где он берет параметры экрана, список плагинов, и т.д. потому что их в ноде нет...

и я хз как оно должно работать, но какие-то числа меняются...

в этом все равно никакого смысла нет, нужен железный аппарат, т.к. компьютерный рэндом, не такой и рэндом, пусть даже у каждого браузера свои размеры и какие-то доп. параметры...
Ответить с цитированием