hash - generar - sha256 decrypt
¿Hay implementaciones de javascript SHA-256 que generalmente se consideran confiables? (7)
Además de la lib de Stanford que Tylerl mencionó. Encontré jsrsasign muy útil (repositorio de Github aquí: https://github.com/kjur/jsrsasign ). No sé qué tan confiable es, pero he usado su API de SHA256, Base64, RSA, x509, etc. y funciona bastante bien. De hecho, incluye la lib de Stanford también.
Si todo lo que quiere hacer es SHA256, jsrsasign puede ser una exageración. Pero si tiene otras necesidades en el área relacionada, creo que es una buena opción.
Estoy escribiendo un inicio de sesión para un foro, y necesito usar la contraseña del lado del cliente en javascript antes de enviarla al servidor. Tengo problemas para descubrir en qué implementación de SHA-256 puedo confiar. Esperaba que hubiera algún tipo de script autoritario que todos usaran, pero estoy encontrando muchos proyectos diferentes, todos con sus propias implementaciones.
Me doy cuenta de que usar crypto de otras personas siempre es un acto de fe a menos que esté calificado para revisarlo usted mismo, y que no existe una definición universal de "confiable", pero esto parece ser algo común e importante que debería haber algún tipo de de consenso sobre qué usar. ¿Soy ingenuo?
Editar ya que aparece mucho en los comentarios: Sí, hacemos un hash más estricto de nuevo en el lado del servidor. El hash del lado del cliente no es el resultado final que guardamos en la base de datos. El hash del lado del cliente se debe a que el cliente humano lo solicita. No han dado una razón específica por la cual, probablemente les gusta exagerar.
En https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest encontré este fragmento que usa el módulo interno js:
async function sha256(message) {
// encode as UTF-8
const msgBuffer = new TextEncoder(''utf-8'').encode(message);
// hash the message
const hashBuffer = await crypto.subtle.digest(''SHA-256'', msgBuffer);
// convert ArrayBuffer to Array
const hashArray = Array.from(new Uint8Array(hashBuffer));
// convert bytes to hex string
const hashHex = hashArray.map(b => (''00'' + b.toString(16)).slice(-2)).join('''');
return hashHex;
}
Encontré esta implementación muy fácil de usar. También tiene una generosa licencia de estilo BSD:
jsSHA: https://github.com/Caligatio/jsSHA
Necesitaba una forma rápida de obtener la representación de cadena hexadecimal de un hash SHA-256. Solo tomó 3 líneas:
var sha256 = new jsSHA(''SHA-256'', ''TEXT'');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");
La biblioteca de criptografía Stanford JS contiene una implementación de SHA-256. Aunque crypto en JS no es una tarea tan bien examinada como otras plataformas de implementación, esta es desarrollada, al menos parcialmente, por, y en cierta medida patrocinada por, Dan Boneh , quien es un nombre bien establecido y confiable en criptografía , y significa que el proyecto tiene cierta supervisión de alguien que realmente sabe lo que está haciendo. El proyecto también es apoyado por la NSF .
Vale la pena señalar, sin embargo ...
... que si hash la contraseña del lado del cliente antes de enviarla, entonces el hash es la contraseña y la contraseña original se vuelve irrelevante. Un atacante solo necesita interceptar el hash para suplantar al usuario, y si ese hash se almacena sin modificaciones en el servidor, entonces el servidor está almacenando la contraseña verdadera (el hash) en texto sin formato .
Entonces, su seguridad ahora es peor porque decidió agregar sus propias mejoras a lo que anteriormente era un esquema confiable.
La implementación de SHA-256 de Forge es rápida y confiable.
Para ejecutar pruebas en varias implementaciones de SHA-256 JavaScript, vaya a http://brillout.github.io/test-javascript-hash-implementations/ .
Los resultados en mi máquina sugieren forge para ser la implementación más rápida y también considerablemente más rápida que la biblioteca de cifrado de JavaScript de Stanford (sjcl) mencionada en la respuesta aceptada.
Forge tiene 256 KB de tamaño, pero extraer el código relacionado con SHA-256 reduce el tamaño a 4.5 KB, consulte https://github.com/brillout/forge-sha256
No, no hay forma de usar el JavaScript del navegador para mejorar la seguridad de las contraseñas. Le recomiendo que lea este artículo . En su caso, el mayor problema es el problema del huevo de gallina:
¿Cuál es el "problema del huevo de gallina" con la entrega de criptografía Javascript?
Si no confía en que la red le entregue una contraseña o, lo que es peor, no confíe en que el servidor no guardará los secretos de los usuarios, no puede confiar en que entreguen un código de seguridad. El mismo atacante que estaba oliendo contraseñas o leyendo diarios antes de introducir crypto es simplemente secuestrando el código criptográfico después de que lo haga.
[...]
¿Por qué no puedo usar TLS / SSL para entregar el código criptográfico Javascript?
Usted puede. Es más difícil de lo que parece, pero usted transmite Javascript crypto a un navegador usando SSL. El problema es que, al haber establecido un canal seguro con SSL, ya no necesita la criptografía de Javascript; tienes una criptografía "real"
Lo que lleva a esto:
El problema con la ejecución de código criptográfico en Javascript es que prácticamente cualquier función de la que depende la criptografía puede ser anulada silenciosamente por cualquier contenido utilizado para construir la página de alojamiento. La seguridad criptográfica podría deshacerse temprano en el proceso (generando números aleatorios falsos o alterando las constantes y los parámetros utilizados por los algoritmos) o más tarde (devolviendo el material clave a un atacante), o --- en el escenario más probable --- evitando completamente la criptografía
No existe una forma confiable para que ningún fragmento de código JavaScript verifique su entorno de ejecución. El código criptográfico Javascript no puede preguntar, "¿realmente estoy lidiando con un generador de números aleatorios, o con algún facsímil de uno proporcionado por un atacante?" Y ciertamente no puede afirmar que "nadie tiene permitido hacer nada con este secreto criptográfico excepto en formas que yo, el autor, apruebo". Estas son dos propiedades que a menudo se proporcionan en otros entornos que usan cifrado, y son imposibles en Javascript.
Básicamente el problema es este:
- Sus clientes no confían en sus servidores, por lo que desean agregar un código de seguridad adicional.
- Ese código de seguridad es entregado por sus servidores (aquellos en los que no confían).
O alternativamente,
- Sus clientes no confían en SSL, por lo que desean que use un código de seguridad adicional.
- Ese código de seguridad se entrega a través de SSL.
Nota: Además, SHA-256 no es adecuado para esto, ya que es muy fácil usar fuerza bruta para contraseñas sin saltos . Si decide hacer esto de todos modos, busque una implementación de bcrypt , scrypt o PBKDF2 .
Para aquellos interesados, este es el código para crear hash SHA-256 usando sjcl
:
import sjcl from ''sjcl''
const myString = ''Hello''
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)