Uma biblioteca de algoritmos de criptografia compatível com ES6 e TypeScript
Instalação:
yarn add crypto-es
Nos projetos Node.js, recomendamos que você use módulos Ecmascript INSEAD of Commonjs:
// package.json
{
"type": "module"
}
Então você pode importar criptos:
import CryptoES from 'crypto-es';
const rst = CryptoES.MD5("Message").toString();
Ou importe parcialmente a função para reduzir o peso da embalagem:
import { MD5 } from 'crypto-es/lib/md5.js';
const rst = MD5("Message").toString();
Cada arquivo nesta biblioteca possui seu próprio arquivo .d.ts agora, por isso está disponível para importar arquivos de algoritmo único parcialmente em projetos tipyscript.
Da mesma forma que Cryptojs
MD5
MD5 é uma função de hash amplamente usada. Ele foi usado em uma variedade de aplicativos de segurança e também é comumente usado para verificar a integridade dos arquivos. No entanto, o MD5 não é resistente à colisão e não é adequado para aplicações como certificados SSL ou assinaturas digitais que dependem dessa propriedade.
const hash = CryptoES.MD5("Message");
SHA-1
As funções SHA Hash foram projetadas pela Agência de Segurança Nacional (NSA). O SHA-1 é o mais estabelecido das funções de hash SHA existente e é usado em uma variedade de aplicativos e protocolos de segurança. No entanto, a resistência à colisão do SHA-1 tem sido enfraquecendo à medida que novos ataques são descobertos ou melhorados.
const hash = CryptoES.SHA1("Message");
SHA-2
O SHA-256 é uma das quatro variantes no conjunto SHA-2. Não é tão amplamente utilizado quanto o SHA-1, embora pareça fornecer uma segurança muito melhor.
const hash = CryptoES.SHA256("Message");
O SHA-512 é amplamente idêntico ao SHA-256, mas opera com palavras de 64 bits em vez de 32.
const hash = CryptoES.SHA512("Message");
As criptas também suportam SHA-224 e SHA-384, que são versões amplamente idênticas, mas truncadas de SHA-256 e SHA-512, respectivamente.
SHA-3
O SHA-3 é o vencedor de uma competição de cinco anos a selecionar um novo algoritmo de hash criptográfico, onde 64 projetos concorrentes foram avaliados.
Nota: cometi um erro ao nomear esta implementação SHA-3. Deve ser nomeado Keccak [C = 2d]. Cada uma das funções SHA-3 é baseada em uma instância do algoritmo Keccak, que o NIST selecionou como o vencedor da competição SHA-3, mas essas funções SHA-3 não produzirão hashes idênticos a Keccak.
const hash = CryptoES.SHA3("Message");
O SHA-3 pode ser configurado para produzir comprimentos de hash de um dos 224, 256, 384 ou 512 bits. O padrão é de 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");
Os algoritmos de hash aceitam strings ou instâncias de criptotes.lib.wordArray. Um objeto WordArray representa uma matriz de palavras de 32 bits. Quando você passa uma string, ela é automaticamente convertida em um WordArray codificado como UTF-8.
O hash que você volta ainda não é uma string. É um objeto WordArray. Quando você usa um objeto WordArray em um contexto de string, ele é automaticamente convertido em uma string hexadecimal.
const hash = CryptoES.SHA256("Message");
alert(typeof hash); // object
alert(hash); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
Você pode converter um objeto WordArray para outros formatos chamando explicitamente o método da tostragem e passando um 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();
Os códigos de autenticação de mensagem-chave-hash (HMAC) são um mecanismo para autenticação de mensagem usando funções de hash criptográfico.
O HMAC pode ser usado em combinação com qualquer função 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 é uma função de derivação de chave baseada em senha. Em muitas aplicações de criptografia, a segurança do usuário depende de uma senha e, como uma senha geralmente não pode ser usada diretamente como uma chave criptográfica, é necessário algum processamento.
Um sal fornece um grande conjunto de chaves para qualquer senha, e uma contagem de iteração aumenta o custo da produção de chaves a partir de uma senha, aumentando também a dificuldade de 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
O padrão de criptografia avançado (AES) é um padrão de processamento de informações federais dos EUA (FIPS). Foi selecionado após um processo de cinco anos em que 15 projetos concorrentes foram avaliados.
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.AES.decrypt(encrypted, "Secret Passphrase");
As criptas suportam o AES-128, AES-192 e AES-256. Ele escolherá a variante pelo tamanho da chave que você passa. Se você usar uma senha, ele gerará uma chave de 256 bits.
DES, Triple des
O DES é um algoritmo anteriormente dominante para criptografia e foi publicado como um padrão oficial de processamento de informações federais (FIPS). O DES agora é considerado inseguro devido ao tamanho pequeno da chave.
const encrypted = CryptoES.DES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.DES.decrypt(encrypted, "Secret Passphrase");
O Triple Des se aplica três vezes a cada bloco para aumentar o tamanho da chave. Acredita -se que o algoritmo esteja seguro nesta forma.
const encrypted = CryptoES.TripleDES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.TripleDES.decrypt(encrypted, "Secret Passphrase");
Coelho
O coelho é uma cifra de fluxo de alto desempenho e finalista no portfólio Estream. É um dos quatro projetos selecionados após um processo de 3 1/2 anos em que 22 projetos foram avaliados.
const encrypted = CryptoES.Rabbit.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.Rabbit.decrypt(encrypted, "Secret Passphrase");
RC4, RC4DROP
O RC4 é uma cifra de fluxo amplamente usada. É usado em protocolos populares, como SSL e WEP. Embora notável por sua simplicidade e velocidade, a história do algoritmo não inspira confiança em sua segurança.
const encrypted = CryptoES.RC4.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.RC4.decrypt(encrypted, "Secret Passphrase");
Descobriu-se que os primeiros bytes do KeyStream são fortemente não-aleatórios e vazam informações sobre a chave. Podemos se defender contra esse ataque descartando a parte inicial da forma de chave. Esse algoritmo modificado é tradicionalmente chamado de RC4-Drop.
Por padrão, 192 palavras (768 bytes) são descartadas, mas você pode configurar o algoritmo para abandonar qualquer número de palavras.
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 });
Blowfish
O Blowfish é uma cifra de bloco de teclas simétricas, projetada em 1993 por Bruce Schneier e incluída em muitas suítes cifras e produtos de criptografia. O Blowfish fornece uma boa taxa de criptografia no software, e nenhuma análise de criptografia eficaz foi encontrada até o momento. No entanto, o padrão de criptografia avançado (AES) agora recebe mais atenção, e Schneier recomenda o Twofish para aplicações modernas.
Schneier projetou o Blowfish como um algoritmo de uso geral, destinado a uma alternativa ao envelhecimento e livre dos problemas e restrições associadas a outros algoritmos. Na época em que o Blowfish foi lançado, muitos outros designs eram proprietários, sobrecarregados por patentes ou eram segredos comerciais ou governamentais. Schneier afirmou que "o Blowfish não está patente e permanecerá assim em todos os países. O algoritmo é colocado em domínio público e pode ser usado livremente por qualquer pessoa".
Os recursos notáveis do design incluem caixas S dependentes de chave e uma programação-chave altamente complexa.
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 });
As criptas suportam os seguintes modos:
E as criptas suportam os seguintes esquemas de preenchimento:
Para a mensagem de texto simples, os algoritmos cifra aceitam strings ou instâncias de criptotes.lib.wordArray.
Para a chave, quando você passa uma corda, ela é tratada como uma senha e usada para derivar uma chave real e IV. Ou você pode passar um WordArray que representa a chave real. Se você passar na chave real, também deverá passar no IV real.
Para o texto cifrado, os algoritmos da cifra aceitam strings ou instâncias de criptotes.lib.cipherparams. Um objeto Cipherparams representa uma coleção de parâmetros como o IV, um sal e o próprio texto cru. Quando você passa uma string, ela é automaticamente convertida em um objeto Cipherparams de acordo com uma estratégia de formato configurável.
O texto simples que você volta após a descriptografia é um objeto WordArray. Veja a saída dos hashers para obter mais detalhes.
O CipherText que você volta após a criptografia ainda não é uma string. É um objeto Cipherparams. Um objeto Cipherparams fornece acesso a todos os parâmetros usados durante a criptografia. Quando você usa um objeto Cipherparams em um contexto de string, ele é automaticamente convertido em uma string de acordo com uma estratégia de formato. O padrão é um formato compatível com o 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=
Você pode definir seus próprios formatos para ser compatível com outras implementações de criptografia. Um formato é um objeto com dois métodos - estringificação e análise - que converte entre objetos Cipherparams e strings de texto cifrado.
Veja como você pode escrever um formatador 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();
Com openSSL
Encrypt com openSSL:
openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64
Descriptografar com as criptas:
const decrypted = CryptoES.AES.decrypt(openSSLEncrypted, "Secret Passphrase");
As criptas podem converter de formatos de codificação como Base64, Latin1 ou Hex para Objetos WordArray e 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);
O criador do WordArray poderia receber um ArrayBuffer ou TypeDArray para que os algorismos de criptotes pudessem se aplicar a eles:
const words = CryptoES.lib.WordArray.create(new ArrayBuffer(8));
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
NOTA : O ArrayBuffer não pôde passar diretamente para algorismos, você deve alterá -los para o WordArray primeiro.
Com isso, criptografar arquivos seria mais 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')
...
};
Alterar log
Refatorando criptojs no ECMAScript moderno