Una biblioteca de algoritmos de criptografía compatible con ES6 y TypeScript
Instalación:
yarn add crypto-es
En los proyectos Node.js, le recomendamos que use módulos ECMAScript Insad of CommonJS:
// package.json
{
"type": "module"
}
Entonces puedes importar criptoes:
import CryptoES from 'crypto-es';
const rst = CryptoES.MD5("Message").toString();
O importar parcialmente la función para reducir el peso del paquete:
import { MD5 } from 'crypto-es/lib/md5.js';
const rst = MD5("Message").toString();
Cada archivo en esta biblioteca tiene su propio archivo .d.ts ahora, por lo que está disponible para importar parcialmente archivos de algoritmo único en proyectos de TypeScript.
Igual que los criptojs
MD5
MD5 es una función hash ampliamente utilizada. Se ha utilizado en una variedad de aplicaciones de seguridad y también se usa comúnmente para verificar la integridad de los archivos. Sin embargo, MD5 no es resistente a la colisión, y no es adecuado para aplicaciones como certificados SSL o firmas digitales que dependen de esta propiedad.
const hash = CryptoES.MD5("Message");
SHA-1
Las funciones de Sha hash fueron diseñadas por la Agencia de Seguridad Nacional (NSA). SHA-1 es la más establecida de las funciones existentes de Sha hash, y se usa en una variedad de aplicaciones y protocolos de seguridad. Sin embargo, la resistencia a la colisión de Sha-1 se ha debilitado a medida que se descubren o mejoran nuevos ataques.
const hash = CryptoES.SHA1("Message");
SHA-2
SHA-256 es una de las cuatro variantes en el conjunto SHA-2. No se usa tan ampliamente como SHA-1, aunque parece proporcionar una seguridad mucho mejor.
const hash = CryptoES.SHA256("Message");
SHA-512 es en gran medida idéntico a SHA-256, pero opera con palabras de 64 bits en lugar de 32.
const hash = CryptoES.SHA512("Message");
Cryptoes también admite SHA-224 y SHA-384, que son versiones en gran medida idénticas pero truncadas de SHA-256 y SHA-512 respectivamente.
SHA-3
SHA-3 es el ganador de una competencia de cinco años para seleccionar un nuevo algoritmo de hash criptográfico donde se evaluaron 64 diseños competidores.
Nota: cometí un error cuando llamé a esta implementación SHA-3. Debe llamarse keccak [c = 2d]. Cada una de las funciones SHA-3 se basa en una instancia del algoritmo Keccak, que NIST seleccionó como el ganador de la competencia SHA-3, pero esas funciones SHA-3 no producirán hashes idénticos a Keccak.
const hash = CryptoES.SHA3("Message");
SHA-3 se puede configurar para emitir longitudes hash de una de 224, 256, 384 o 512 bits. El valor predeterminado es 512 bits.
const hash = CryptoES.SHA3("Message", { outputLength: 512 });
const hash = CryptoES.SHA3("Message", { outputLength: 384 });
const hash = CryptoES.SHA3("Message", { outputLength: 256 });
const hash = CryptoES.SHA3("Message", { outputLength: 224 });
RIPEMD-160
const hash = CryptoES.RIPEMD160("Message");
Los algoritmos hash aceptan cadenas o instancias de cryptoes.lib.wordArray. Un objeto WordArray representa una matriz de palabras de 32 bits. Cuando pasa una cadena, se convierte automáticamente en un WordArray codificado como UTF-8.
El hash que recuperas aún no es una cadena. Es un objeto WordArray. Cuando usa un objeto WordArray en un contexto de cadena, se convierte automáticamente en una cadena hexadecimal.
const hash = CryptoES.SHA256("Message");
alert(typeof hash); // object
alert(hash); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
Puede convertir un objeto WordArray a otros formatos llamando explícitamente el método de tostración y pasando un codificador.
const hash = CryptoES.SHA256("Message");
alert(hash.toString(CryptoES.enc.Base64)); // L3dmip37+NWEi57rSnFFypTG7ZI25Kdz9tyvpRMrL5E= alert(hash.toString(CryptoES.enc.Latin1)); // /wf��ûøÕ���ëJqEÊ�Æí�6ä§söܯ¥�+/�
alert(hash.toString(CryptoES.enc.Hex)); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
const sha256 = CryptoES.algo.SHA256.create();
sha256.update("Message Part 1");
sha256.update("Message Part 2");
sha256.update("Message Part 3");
const hash = sha256.finalize();
Los códigos de autenticación de mensajes de Keyed-Hash (HMAC) es un mecanismo para la autenticación de mensajes utilizando funciones de hash criptográfico.
HMAC se puede usar en combinación con cualquier función de hash criptográfica iterada.
const hash = CryptoES.HmacMD5("Message", "Secret Passphrase");
const hash = CryptoES.HmacSHA1("Message", "Secret Passphrase");
const hash = CryptoES.HmacSHA256("Message", "Secret Passphrase");
const hash = CryptoES.HmacSHA512("Message", "Secret Passphrase");
const hmac = CryptoES.algo.HMAC.create(CryptoES.algo.SHA256, "Secret Passphrase");
hmac.update("Message Part 1");
hmac.update("Message Part 2");
hmac.update("Message Part 3");
const hash = hmac.finalize();
PBKDF2 es una función de derivación de clave basada en contraseña. En muchas aplicaciones de criptografía, la seguridad del usuario depende en última instancia de una contraseña, y debido a que una contraseña generalmente no se puede usar directamente como clave criptográfica, se requiere algo de procesamiento.
Una sal proporciona un gran conjunto de claves para cualquier contraseña determinada, y un recuento de iteraciones aumenta el costo de producir claves desde una contraseña, lo que también aumenta la dificultad del ataque.
const salt = CryptoES.lib.WordArray.random(128/8);
const key128Bits = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 128/32 });
const key256Bits = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 256/32 });
const key512Bits = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 512/32 });
const key512Bits1000Iterations = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 512/32, iterations: 1000 });
AES
El estándar de cifrado avanzado (AES) es un estándar de procesamiento de información federal de EE. UU. (FIPS). Fue seleccionado después de un proceso de 5 años donde se evaluaron 15 diseños competidores.
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.AES.decrypt(encrypted, "Secret Passphrase");
Cryptoes admite AES-128, AES-192 y AES-256. Elegirá la variante por el tamaño de la clave que pasa. Si usa una frase de pases, generará una clave de 256 bits.
Des, triple des
DES es un algoritmo previamente dominante para el cifrado, y fue publicado como un estándar oficial de procesamiento de información federal (FIPS). AS ahora se considera inseguro debido al pequeño tamaño de la llave.
const encrypted = CryptoES.DES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.DES.decrypt(encrypted, "Secret Passphrase");
Triple DES se aplica tres veces a cada bloque para aumentar el tamaño de la clave. Se cree que el algoritmo es seguro en esta forma.
const encrypted = CryptoES.TripleDES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.TripleDES.decrypt(encrypted, "Secret Passphrase");
Conejo
Rabbit es un cifrado de flujo de alto rendimiento y un finalista en la cartera de Estream. Es uno de los cuatro diseños seleccionados después de un proceso de 3 1/2 años donde se evaluaron 22 diseños.
const encrypted = CryptoES.Rabbit.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.Rabbit.decrypt(encrypted, "Secret Passphrase");
RC4, RC4Drop
RC4 es un cifrado de flujo ampliamente utilizado. Se usa en protocolos populares como SSL y WEP. Aunque es notable por su simplicidad y velocidad, la historia del algoritmo no inspira confianza en su seguridad.
const encrypted = CryptoES.RC4.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.RC4.decrypt(encrypted, "Secret Passphrase");
Se descubrió que los primeros bytes de la llave de teclas son fuertemente no aleatorias y de fuga de información sobre la clave. Podemos defendernos contra este ataque descartando la parte inicial de la corriente de tecla. Este algoritmo modificado se llama tradicionalmente RC4-DROP.
Por defecto, se eliminan 192 palabras (768 bytes), pero puede configurar el algoritmo para soltar cualquier cantidad de palabras.
const encrypted = CryptoES.RC4Drop.encrypt("Message", "Secret Passphrase");
const encrypted = CryptoES.RC4Drop.encrypt("Message", "Secret Passphrase", { drop: 3072/4 });
const decrypted = CryptoES.RC4Drop.decrypt(encrypted, "Secret Passphrase", { drop: 3072/4 });
Pescado
Blowfish es un cifrado de bloques simétrico, diseñado en 1993 por Bruce Schneier e incluida en muchas suites de cifrado y productos de cifrado. Blowfish proporciona una buena tasa de cifrado en el software, y hasta la fecha no se ha encontrado criptoanálisis efectivo. Sin embargo, el estándar de cifrado avanzado (AES) ahora recibe más atención, y Schneier recomienda TWOFISH para aplicaciones modernas.
Schneier diseñó Blowfish como un algoritmo de uso general, destinado a ser una alternativa al envejecimiento del DES y libre de los problemas y restricciones asociadas con otros algoritmos. En ese momento se lanzó Blowfish, muchos otros diseños eran propietarios, gravados por patentes, o eran secretos comerciales o gubernamentales. Schneier ha declarado que "el pescado de soporte no está satisfecho y seguirá siendo así en todos los países. El algoritmo se coloca en el dominio público y puede ser utilizado libremente por cualquiera".
Las características notables del diseño incluyen cajas S dependientes de la llave y un horario clave altamente complejo.
const ciphertext = CryptoJS.Blowfish.encrypt(message, key, cfg);
const plaintext = CryptoJS.Blowfish.decrypt(ciphertext, key, cfg);
const key = CryptoES.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
const iv = CryptoES.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
const encrypted = CryptoES.AES.encrypt("Message", key, { iv: iv });
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase", { mode: CryptoES.mode.CFB, padding: CryptoES.pad.AnsiX923 });
Cryptoes admite los siguientes modos:
Y Cryptoes admite los siguientes esquemas de relleno:
Para el mensaje de texto sin formato, los algoritmos de cifrado aceptan cadenas o instancias de criptoes.lib.wordArray.
Para la clave, cuando pasa una cadena, se trata como una frase de pases y se usa para derivar una clave real e IV. O puede pasar un WordArray que represente la clave real. Si pasa la clave real, también debe pasar el IV real.
Para el texto cifrado, los algoritmos de cifrado aceptan cadenas o instancias de criptoes.lib.cipherparams. Un objeto Cipherparams representa una colección de parámetros como el IV, una sal y el cifrado crudo en sí. Cuando pasa una cadena, se convierte automáticamente en un objeto CipherParams de acuerdo con una estrategia de formato configurable.
El texto sin formato que recupere después del descifrado es un objeto WordArray. Vea la salida de los hashers para obtener más detalles.
El texto cifrado que recuperas después del cifrado aún no es una cadena. Es un objeto Cipherparams. Un objeto Cipherparams le da acceso a todos los parámetros utilizados durante el cifrado. Cuando usa un objeto CipherParams en un contexto de cadena, se convierte automáticamente en una cadena de acuerdo con una estrategia de formato. El valor predeterminado es un formato compatible con OpenSSL.
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase"); alert(encrypted.key); // 74eb593087a982e2a6f5dded54ecd96d1fd0f3d44a58728cdcd40c55227522223
alert(encrypted.iv); // 7781157e2629b094f0e3dd48c4d786115
alert(encrypted.salt); // 7a25f9132ec6a8b34
alert(encrypted.ciphertext); // 73e54154a15d1beeb509d9e12f1e462a0
alert(encrypted); // U2FsdGVkX1+iX5Ey7GqLND5UFUoV0b7rUJ2eEvHkYqA=
Puede definir sus propios formatos para ser compatible con otras implementaciones de cifrado. Un formato es un objeto con dos métodos, firmar y analizar, que se convierte entre los objetos Cipherparams y las cadenas de texto cifrado.
Así es como podrías escribir un formateador JSON:
const JsonFormatter = {
stringify: function (cipherParams) { // create json object with ciphertext
const jsonObj = { ct: cipherParams.ciphertext.toString(CryptoES.enc.Base64) }; // optionally add iv and salt
if (cipherParams.iv) {
jsonObj.iv = cipherParams.iv.toString();
}
if (cipherParams.salt) {
jsonObj.s = cipherParams.salt.toString();
}
// stringify json object
return JSON.stringify(jsonObj);
},
parse: function (jsonStr) { // parse json string
const jsonObj = JSON.parse(jsonStr); // extract ciphertext from json object, and create cipher params object
const cipherParams = CryptoES.lib.CipherParams.create(
{ ciphertext: CryptoES.enc.Base64.parse(jsonObj.ct) },
); // optionally extract iv and salt
if (jsonObj.iv) {
cipherParams.iv = CryptoES.enc.Hex.parse(jsonObj.iv)
}
if (jsonObj.s) {
cipherParams.salt = CryptoES.enc.Hex.parse(jsonObj.s)
}
return cipherParams;
},
};
const encrypted = CryptoES.AES.encrypt(
"Message",
"Secret Passphrase",
{ format: JsonFormatter },
);
alert(encrypted); // {"ct":"tZ4MsEnfbcDOwqau68aOrQ==","iv":"8a8c8fd8fe33743d3638737ea4a00698","s":"ba06373c8f57179c"}
const decrypted = CryptoES.AES.decrypt(
encrypted,
"Secret Passphrase",
{ format: JsonFormatter },
);
alert(decrypted.toString(CryptoES.enc.Utf8)); // Message
const key = CryptoES.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
const iv = CryptoES.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
const aesEncryptor = CryptoES.algo.AES.createEncryptor(key, { iv: iv });
const ciphertextPart1 = aesEncryptor.process("Message Part 1");
const ciphertextPart2 = aesEncryptor.process("Message Part 2");
const ciphertextPart3 = aesEncryptor.process("Message Part 3");
const ciphertextPart4 = aesEncryptor.finalize();
const aesDecryptor = CryptoES.algo.AES.createDecryptor(key, { iv: iv });
const plaintextPart1 = aesDecryptor.process(ciphertextPart1);
const plaintextPart2 = aesDecryptor.process(ciphertextPart2);
const plaintextPart3 = aesDecryptor.process(ciphertextPart3);
const plaintextPart4 = aesDecryptor.process(ciphertextPart4);
const plaintextPart5 = aesDecryptor.finalize();
Con openssl
Cifrar con OpenSSL:
openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64
Descifrar con criptoes:
const decrypted = CryptoES.AES.decrypt(openSSLEncrypted, "Secret Passphrase");
Las criptoes pueden convertirse de formatos de codificación como Base64, Latin1 o Hex a WordArray Objects y Vica Versa.
const words = CryptoES.enc.Base64.parse('SGVsbG8sIFdvcmxkIQ==');
const base64 = CryptoES.enc.Base64.stringify(words);
const words = CryptoES.enc.Base64url.parse('SGVsbG8sIFdvcmxkIQ==');
const base64url = CryptoES.enc.Base64.stringify(words);
const words = CryptoES.enc.Latin1.parse('Hello, World!');
const latin1 = CryptoES.enc.Latin1.stringify(words);
const words = CryptoES.enc.Hex.parse('48656c6c6f2c20576f726c6421');
const hex = CryptoES.enc.Hex.stringify(words);
const words = CryptoES.enc.Utf8.parse('?');
const utf8 = CryptoES.enc.Utf8.stringify(words);
const words = CryptoES.enc.Utf16.parse('Hello, World!');
const utf16 = CryptoES.enc.Utf16.stringify(words);
const words = CryptoES.enc.Utf16LE.parse('Hello, World!');
const utf16 = CryptoES.enc.Utf16LE.stringify(words);
WordArray Creator podría recivar un ArrayBuffer o TypeDArray para que los algorismos de Cryptoes puedan aplicarse a ellos:
const words = CryptoES.lib.WordArray.create(new ArrayBuffer(8));
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
Nota : ArrayBuffer no pudo pasar directamente a los algorismos, primero debe cambiarlos a WordArray.
Con esto, cifrar archivos sería más fácil:
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function () {
const arrayBuffer = reader.result;
const words = CryptoES.lib.WordArray.create(arrayBuffer);
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
...
};
Registro de cambio
Refactorización de criptojs en Ecmascript moderno