Une bibliothèque d'algorithmes de cryptographie compatible avec ES6 et TypeScript
Installation:
yarn add crypto-es
Dans les projets Node.js, nous vous recommandons d'utiliser les modules ECMascript INSEAD de CommonJS:
// package.json
{
"type": "module"
}
Ensuite, vous pouvez importer des cryptoes:
import CryptoES from 'crypto-es';
const rst = CryptoES.MD5("Message").toString();
Ou importe partiellement la fonction pour réduire le poids du package:
import { MD5 } from 'crypto-es/lib/md5.js';
const rst = MD5("Message").toString();
Chaque fichier de cette bibliothèque a son propre fichier .d.ts maintenant, il est donc disponible pour importer partiellement des fichiers d'algorithmes uniques dans des projets TypeScript.
Comme les cryptojs
Md5
MD5 est une fonction de hachage largement utilisée. Il a été utilisé dans une variété d'applications de sécurité et est également couramment utilisé pour vérifier l'intégrité des fichiers. Cependant, MD5 n'est pas résistant aux collisions, et il ne convient pas aux applications telles que les certificats SSL ou les signatures numériques qui reposent sur cette propriété.
const hash = CryptoES.MD5("Message");
Sha-1
Les fonctions de hachage SHA ont été conçues par la National Security Agency (NSA). SHA-1 est la plus établie des fonctions de hachage SHA existantes, et elle est utilisée dans une variété d'applications et de protocoles de sécurité. Cependant, la résistance aux collisions de SHA-1 s'est affaiblie à mesure que de nouvelles attaques sont découvertes ou améliorées.
const hash = CryptoES.SHA1("Message");
Sha-2
Le SHA-256 est l'une des quatre variantes de l'ensemble SHA-2. Il n'est pas aussi largement utilisé que SHA-1, bien qu'il semble assurer une bien meilleure sécurité.
const hash = CryptoES.SHA256("Message");
SHA-512 est largement identique au SHA-256 mais fonctionne sur des mots 64 bits plutôt que 32.
const hash = CryptoES.SHA512("Message");
Les cryptoes prennent également en charge les SHA-224 et SHA-384, qui sont des versions largement identiques mais tronquées de SHA-256 et SHA-512 respectivement.
SHA-3
SHA-3 est le gagnant d'un concours de cinq ans pour sélectionner un nouvel algorithme de hachage cryptographique où 64 conceptions concurrentes ont été évaluées.
Remarque: j'ai fait une erreur lorsque j'ai nommé cette implémentation SHA-3. Il doit être nommé Keccak [c = 2d]. Chacune des fonctions SHA-3 est basée sur une instance de l'algorithme Keccak, que NIST a sélectionné comme gagnant de la compétition SHA-3, mais ces fonctions SHA-3 ne produiront pas de hachages identiques à Keccak.
const hash = CryptoES.SHA3("Message");
SHA-3 peut être configuré pour produire des longueurs de hachage de l'une des 224, 256, 384 ou 512 bits. La valeur par défaut est 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 });
Rimemd-160
const hash = CryptoES.RIPEMD160("Message");
Les algorithmes de hachage acceptent soit des chaînes ou des instances de cryptoes.lib.wordArray. Un objet WordArray représente un tableau de mots 32 bits. Lorsque vous passez une chaîne, il est automatiquement converti en un WordArray codé comme UTF-8.
Le hachage que vous récupérez n'est pas encore une chaîne. C'est un objet WordArray. Lorsque vous utilisez un objet WordArray dans un contexte de chaîne, il est automatiquement converti en chaîne hexagonale.
const hash = CryptoES.SHA256("Message");
alert(typeof hash); // object
alert(hash); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
Vous pouvez convertir un objet WordArray en d'autres formats en appelant explicitement la méthode ToString et en passant un encodeur.
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();
Les codes d'authentification des messages de Hash Keyed (HMAC) sont un mécanisme d'authentification des messages à l'aide des fonctions de hachage cryptographique.
HMAC peut être utilisé en combinaison avec toute fonction de hachage cryptographique itérée.
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 est une fonction de dérivation de clé de mot de passe. Dans de nombreuses applications de cryptographie, la sécurité des utilisateurs dépend finalement d'un mot de passe, et comme un mot de passe ne peut généralement pas être utilisé directement comme clé cryptographique, un traitement est requis.
Un sel fournit un large ensemble de clés pour un mot de passe donné, et un décompte d'itération augmente le coût de production de clés à partir d'un mot de passe, augmentant ainsi également la difficulté d'attaque.
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 });
Stimulation
La norme de chiffrement avancée (AES) est une norme fédérale de traitement des informations américaines (FIPS). Il a été sélectionné après un processus de 5 ans où 15 conceptions concurrentes ont été évaluées.
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.AES.decrypt(encrypted, "Secret Passphrase");
Les cryptoes prennent en charge AES-128, AES-192 et AES-256. Il choisira la variante par la taille de la clé que vous transmettez. Si vous utilisez une phrase secrète, elle générera une clé de 256 bits.
Des, Triple des
Le DES est un algorithme auparavant dominant pour le chiffrement et a été publié en tant que norme officielle de traitement fédéral de l'information (FIPS). Le DES est désormais considéré comme peu sûr en raison de la petite taille de clé.
const encrypted = CryptoES.DES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.DES.decrypt(encrypted, "Secret Passphrase");
Triple DES s'applique trois fois à chaque bloc pour augmenter la taille de la clé. L'algorithme est censé être sécurisé sous cette forme.
const encrypted = CryptoES.TripleDES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.TripleDES.decrypt(encrypted, "Secret Passphrase");
Lapin
Le lapin est un chiffre de flux haute performance et un finaliste dans le portefeuille d'Estream. Il s'agit de l'une des quatre conceptions sélectionnées après un processus de 3 1/2 ans où 22 conceptions ont été évaluées.
const encrypted = CryptoES.Rabbit.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.Rabbit.decrypt(encrypted, "Secret Passphrase");
Rc4, rc4drop
RC4 est un chiffre de flux largement utilisé. Il est utilisé dans des protocoles populaires tels que SSL et WEP. Bien que remarquable par sa simplicité et sa vitesse, l'histoire de l'algorithme n'inspire pas confiance en sa sécurité.
const encrypted = CryptoES.RC4.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.RC4.decrypt(encrypted, "Secret Passphrase");
Il a été découvert que les premiers octets de Keystream sont des informations fortement non aléatoires et fuites sur la clé. Nous pouvons nous défendre contre cette attaque en rejetant la partie initiale du flux de frappe. Cet algorithme modifié est traditionnellement appelé RC4-Drop.
Par défaut, 192 mots (768 octets) sont supprimés, mais vous pouvez configurer l'algorithme pour supprimer n'importe quel nombre de mots.
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 });
Flowfish
Blowfish est un chiffre de blocs à clé symétrique, conçu en 1993 par Bruce Schneier et inclus dans de nombreux suites de chiffres et produits de chiffrement. Blowfish fournit un bon taux de chiffrement dans les logiciels, et aucune cryptanalyse efficace de celui-ci n'a été trouvée à ce jour. Cependant, la norme de chiffrement avancée (AES) reçoit désormais plus d'attention, et Schneier recommande le twofish pour les applications modernes.
Schneier a conçu Blowfish comme un algorithme à usage général, conçu comme une alternative au DES vieillissante et sans problèmes et contraintes associés à d'autres algorithmes. Au moment où Blowfish a été libéré, de nombreux autres conceptions étaient propriétaires, encombrés par des brevets, ou étaient des secrets commerciaux ou gouvernementaux. Schneier a déclaré que "Blowfish n'est pas breveté et le restera dans tous les pays. L'algorithme est placé dans le domaine public et peut être utilisé librement par quiconque."
Les caractéristiques notables de la conception comprennent des boîtes S dépendantes de la clé et un calendrier de clés très complexe.
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 });
Les cryptoes prennent en charge les modes suivants:
Et les cryptoes prennent en charge les schémas de rembourrage suivants:
Pour le message en clair, les algorithmes de chiffre acceptent soit des chaînes ou des instances de cryptoes.lib.wordarray.
Pour la clé, lorsque vous passez une chaîne, elle est traitée comme une phrase secrète et utilisée pour dériver une clé réelle et iv. Ou vous pouvez passer un wordArray qui représente la clé réelle. Si vous passez la clé réelle, vous devez également passer l'IV réel.
Pour le texte chiffré, les algorithmes de chiffre acceptent les chaînes ou les instances de cryptoes.lib.cipherparams. Un objet Cipherparams représente une collection de paramètres tels que l'IV, un sel et le texte chiffré brut lui-même. Lorsque vous passez une chaîne, il est automatiquement converti en un objet Cipherparams en fonction d'une stratégie de format configurable.
Le texte en clair que vous récupérez après décryptage est un objet WordArray. Voir la sortie des Hachers pour plus de détails.
Le texte chiffré que vous récupérez après cryptage n'est pas encore une chaîne. C'est un objet Cipherparams. Un objet Cipherparams vous donne accès à tous les paramètres utilisés pendant le chiffrement. Lorsque vous utilisez un objet Cipherparams dans un contexte de chaîne, il est automatiquement converti en une chaîne en fonction d'une stratégie de format. La valeur par défaut est un format compatible 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=
Vous pouvez définir vos propres formats afin d'être compatibles avec d'autres implémentations de crypto. Un format est un objet avec deux méthodes - Strintify et analyse - qui convertit entre les objets Cipherparams et les chaînes de texte chiffré.
Voici comment vous pourriez écrire un formateur 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();
Avec OpenSSL
Encrypter avec OpenSSL:
openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64
Décrypter avec les cryptoes:
const decrypted = CryptoES.AES.decrypt(openSSLEncrypted, "Secret Passphrase");
Les cryptoes peuvent convertir des formats de codage tels que Base64, Latin1 ou Hex en objets WordArray et 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 pourrait recevoir un ArrayBuffer ou TypedArray afin que les algorismes de cryptoes puissent s'appliquer à eux:
const words = CryptoES.lib.WordArray.create(new ArrayBuffer(8));
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
Remarque : ArrayBuffer n'a pas pu passer directement aux algorismes, vous devez d'abord les changer en wordArray.
Avec cela, le chiffrement des fichiers serait plus facile:
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')
...
};
Modifier le journal
Refactojs de refactorisation dans Ecmascript moderne