nodejs node encrypt decrypt crypto createhmac node.js security

node.js - encrypt - node js crypto



randomBytes vs pseudoRandomBytes (3)

Resulta que, con el OpenSSL predeterminado (que se incluye con el nodo, pero si has creado el tuyo, es posible configurar diferentes motores ), el algoritmo para generar datos aleatorios es exactamente el mismo para ambos randomBytes ( RAND_bytes ) y pseudoRandomBytes ( RAND_pseudo_bytes ).

La única diferencia entre las dos llamadas depende de la versión del nodo que esté utilizando:

  • En el nodo v0.12 y anterior, randomBytes devuelve un error si la agrupación de entropía aún no se ha sembrado con datos suficientes. pseudoRandomBytes siempre devolverá bytes, incluso si el grupo de entropía no se ha sembrado correctamente.
  • En el nodo v4 y posterior, randomBytes no regresa hasta que la agrupación de entropía tenga suficientes datos. Esto debería tomar solo unos pocos milisegundos (a menos que el sistema se haya iniciado).

Una vez que el grupo de entropía se haya sembrado con datos suficientes, nunca se "agotará", por lo que no hay absolutamente ninguna diferencia efectiva entre los randomBytes y los pseudoRandomBytes una vez que el grupo de entropía está lleno .

Debido a que el mismo algoritmo se usa para generar datos de randrom, no hay diferencia en el rendimiento entre las dos llamadas (a pesar de la siembra de entropía de una sola vez).

¿En qué situaciones es aceptable (desde un punto de vista de seguridad) usar crypto.pseudoRandomBytes de nodo en lugar de crypto.pseudoRandomBytes criptográficamente fuertes?

Supongo que los pseudoRandomBytes desempeñan mejor a costa de ser más predecibles ( incorrect ), pero los documentos realmente no tienen mucho que decir acerca de cuán menos fuerte es.

Específicamente, me pregunto si estoy de acuerdo en usar pseudoRandomBytes para generar un token CSRF.


Si se parece en algo a las implementaciones estándar de PRNG en otros idiomas, es probable que no se muestre de forma predeterminada o se genere con un valor simple, como una marca de tiempo. En cualquier caso, la semilla es posiblemente muy fácil de adivinar.


Solo una aclaración, ambos tienen el mismo rendimiento:

var crypto = require ("crypto") var speedy = require ("speedy"); speedy.run ({ randomBytes: function (cb){ crypto.randomBytes (256, cb); }, pseudoRandomBytes: function (cb){ crypto.pseudoRandomBytes (256, cb); } }); /* File: t.js Node v0.10.25 V8 v3.14.5.9 Speedy v0.1.1 Tests: 2 Timeout: 1000ms (1s 0ms) Samples: 3 Total time per test: ~3000ms (3s 0ms) Total time: ~6000ms (6s 0ms) Higher is better (ops/sec) randomBytes 58,836 ± 0.4% pseudoRandomBytes 58,533 ± 0.8% Elapsed time: 6318ms (6s 318ms) */