مكتبة خوارزميات تشفير متوافقة مع ES6 و TypeScript
تثبيت:
yarn add crypto-es
في مشاريع node.js ، نوصيك باستخدام وحدات ecmascript insead من commonjs:
// package.json
{
"type": "module"
}
ثم يمكنك استيراد cryptoes:
import CryptoES from 'crypto-es';
const rst = CryptoES.MD5("Message").toString();
أو استيراد الوظيفة جزئيًا لتقليل وزن الحزمة:
import { MD5 } from 'crypto-es/lib/md5.js';
const rst = MD5("Message").toString();
يحتوي كل ملف في هذه المكتبة على ملف .d.ts الخاص به الآن ، لذلك يتوفر لاستيراد ملفات الخوارزمية المفردة جزئيًا في مشاريع TypeScript.
فقط مثل Cryptojs
MD5
MD5 هي وظيفة التجزئة المستخدمة على نطاق واسع. تم استخدامه في مجموعة متنوعة من تطبيقات الأمان ويستخدم أيضًا للتحقق من سلامة الملفات. على الرغم من أن MD5 ليس مقاومًا للتصادم ، وهو غير مناسب للتطبيقات مثل شهادات SSL أو التواقيع الرقمية التي تعتمد على هذه الخاصية.
const hash = CryptoES.MD5("Message");
شا -1
تم تصميم وظائف التجزئة SHA من قبل وكالة الأمن القومي (NSA). SHA-1 هو الأكثر تأسيسًا في وظائف تجزئة SHA الحالية ، ويتم استخدامها في مجموعة متنوعة من تطبيقات الأمن والبروتوكولات. رغم ذلك ، كانت مقاومة تصادم SHA-1 تضعف حيث يتم اكتشاف أو تحسين الهجمات الجديدة.
const hash = CryptoES.SHA1("Message");
SHA-2
SHA-256 هي واحدة من المتغيرات الأربعة في مجموعة SHA-2. لا يستخدم على نطاق واسع مثل SHA-1 ، على الرغم من أنه يبدو أنه يوفر أمانًا أفضل بكثير.
const hash = CryptoES.SHA256("Message");
يتطابق SHA-512 إلى حد كبير مع SHA-256 ولكنه يعمل على كلمات 64 بت بدلاً من 32.
const hash = CryptoES.SHA512("Message");
يدعم Cryptoes أيضًا SHA-224 و SHA-384 ، والتي تتطابق إلى حد كبير ولكنها مقطوعة من إصدارات SHA-256 و SHA-512 على التوالي.
SHA-3
SHA-3 هو الفائز بمسابقة مدتها خمس سنوات لاختيار خوارزمية تجزئة تشفير جديدة حيث تم تقييم 64 تصميمًا متنافسًا.
ملاحظة: لقد ارتكبت خطأً عندما أسمي هذا التنفيذ SHA-3. يجب تسميته Keccak [C = 2D]. تعتمد كل وظيفة من وظائف SHA-3 على مثيل لخوارزمية Keccak ، التي اختارها NIST كفائز في مسابقة SHA-3 ، لكن وظائف SHA-3 لن تنتج تجزئة مطابقة لـ Keccak.
const hash = CryptoES.SHA3("Message");
يمكن تكوين SHA-3 لإخراج أطوال تجزئة واحدة من 224 أو 256 أو 384 أو 512 بت. الافتراضي هو 512 بت.
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");
تقبل خوارزميات التجزئة إما خيوط أو مثيلات من cryptoes.lib.wordarray. يمثل كائن WordArray مجموعة من الكلمات 32 بت. عند تمرير سلسلة ، يتم تحويلها تلقائيًا إلى WordArray المشفر على أنها UTF-8.
التجزئة التي تعود إليها ليست سلسلة بعد. إنه كائن WordArray. عند استخدام كائن WordArray في سياق سلسلة ، يتم تحويله تلقائيًا إلى سلسلة سداسية.
const hash = CryptoES.SHA256("Message");
alert(typeof hash); // object
alert(hash); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
يمكنك تحويل كائن WordArray إلى تنسيقات أخرى عن طريق استدعاء طريقة ToString صراحة وتمرير التشفير.
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();
تعتبر رموز مصادقة الرسائل ذات المفاتيح الرئيسية (HMAC) آلية لمصادقة الرسائل باستخدام وظائف تجزئة التشفير.
يمكن استخدام HMAC مع أي وظيفة تجزئة التشفير المتكررة.
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 هي وظيفة اشتقاق مفتاح تعتمد على كلمة المرور. في العديد من تطبيقات التشفير ، يعتمد أمان المستخدم في النهاية على كلمة مرور ، ولأن كلمة المرور عادة ما لا يمكن استخدامها مباشرة كمفتاح تشفير ، يلزم بعض المعالجة.
يوفر الملح مجموعة كبيرة من المفاتيح لأي كلمة مرور معينة ، ويزيد عدد التكرار من تكلفة إنتاج المفاتيح من كلمة مرور ، وبالتالي زيادة صعوبة الهجوم.
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
معيار التشفير المتقدم (AES) هو معيار معالجة المعلومات الفيدرالية الأمريكية (FIPS). تم اختياره بعد عملية مدتها 5 سنوات حيث تم تقييم 15 تصميمًا متنافسًا.
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.AES.decrypt(encrypted, "Secret Passphrase");
يدعم Cryptoes AES-128 و AES-192 و AES-256. سيختار البديل بحجم المفتاح الذي تمر به. إذا كنت تستخدم عبارة مرور ، فسيقوم بإنشاء مفتاح 256 بت.
des ، triple des
DES هي خوارزمية مهيمنة سابقًا للتشفير ، وتم نشرها كمعيار رسمي لمعالجة المعلومات الفيدرالية (FIPS). تعتبر DES الآن غير آمنة بسبب حجم المفتاح الصغير.
const encrypted = CryptoES.DES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.DES.decrypt(encrypted, "Secret Passphrase");
يطبق Triple DES DES ثلاث مرات على كل كتلة لزيادة حجم المفتاح. ويعتقد أن الخوارزمية آمنة في هذا النموذج.
const encrypted = CryptoES.TripleDES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.TripleDES.decrypt(encrypted, "Secret Passphrase");
أرنب
Rabbit هو تشفير تيار عالي الأداء ونهائي في محفظة Estream. إنها واحدة من التصميمات الأربعة التي تم اختيارها بعد عملية 3/2 سنوات حيث تم تقييم 22 تصميمًا.
const encrypted = CryptoES.Rabbit.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.Rabbit.decrypt(encrypted, "Secret Passphrase");
RC4 ، RC4DROP
RC4 هو تشفير تيار يستخدم على نطاق واسع. يتم استخدامه في البروتوكولات الشعبية مثل SSL و WEP. على الرغم من أنه رائع بالنسبة لبساطتها وسرعتها ، فإن تاريخ الخوارزمية لا يلهم الثقة في أمنها.
const encrypted = CryptoES.RC4.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.RC4.decrypt(encrypted, "Secret Passphrase");
اكتشف أن بايتات المفاتيح القليلة الأولى هي معلومات غير عشوائية وتسرب بقوة حول المفتاح. يمكننا الدفاع عن هذا الهجوم من خلال التخلص من الجزء الأولي من المفتاح. تسمى هذه الخوارزمية المعدلة تقليديًا RC4-drop.
بشكل افتراضي ، يتم إسقاط 192 كلمة (768 بايت) ، ولكن يمكنك تكوين الخوارزمية لإسقاط أي عدد من الكلمات.
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 عبارة عن تشفير كتلة متماثل ، تم تصميمه في عام 1993 من قبل Bruce Schneier وتم تضمينه في العديد من أجنحة التشفير ومنتجات التشفير. يوفر Blowfish معدل تشفير جيد في البرمجيات ، ولم يتم العثور على تحليل تشفير فعال منه حتى الآن. ومع ذلك ، فإن معيار التشفير المتقدم (AES) يحظى الآن بمزيد من الاهتمام ، ويوصي Schneier بملفقة للتطبيقات الحديثة.
صمم Schneier أسماك Blowfish كخوارزمية للأغراض العامة ، المقصود كبديل للشيخوخة DES وخالية من المشكلات والقيود المرتبطة بالخوارزميات الأخرى. في الوقت الذي تم فيه إطلاق Blowfish ، كانت العديد من التصميمات الأخرى ملكية ، أو رهيبة براءات الاختراع ، أو كانت أسرار تجارية أو حكومية. صرح شنير بأن "أسماك النفخ غير مصممة ، وسيظل كذلك في جميع البلدان. يتم وضع الخوارزمية بموجبها في المجال العام ، ويمكن استخدامها بحرية من قبل أي شخص."
تشمل الميزات البارزة للتصميم صناديق S المعتمدة على المفاتيح وجدول مفتاح معقد للغاية.
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 الأوضاع التالية:
ويدعم Cryptoes مخططات الحشو التالية:
بالنسبة لرسالة النص العادي ، تقبل خوارزميات التشفير إما سلاسل أو مثيلات من cryptoes.lib.wordarray.
بالنسبة للمفتاح ، عند تمرير سلسلة ، يتم التعامل معها كصاحبة مرور وتستخدم لاستخلاص مفتاح فعلي و IV. أو يمكنك تمرير WordArray الذي يمثل المفتاح الفعلي. إذا قمت بتمرير المفتاح الفعلي ، فيجب عليك أيضًا تمرير IV الفعلي.
بالنسبة إلى النص المشفر ، تقبل خوارزميات التشفير إما سلاسل أو حالات من cryptoes.lib.cipherparams. يمثل كائن Cipherparams مجموعة من المعلمات مثل IV والملح والنص المشفر الخام نفسه. عند تمرير سلسلة ، يتم تحويلها تلقائيًا إلى كائن Cipherparams وفقًا لاستراتيجية التنسيق القابلة للتكوين.
النص العادي الذي تعود إليه بعد فك التشفير هو كائن WordArray. انظر خرج هاشر لمزيد من التفاصيل.
النص المشفر الذي تعود إليه بعد التشفير ليس سلسلة حتى الآن. إنه كائن Cipherparams. يمنحك كائن Cipherparams الوصول إلى جميع المعلمات المستخدمة أثناء التشفير. عند استخدام كائن Cipherparams في سياق سلسلة ، يتم تحويله تلقائيًا إلى سلسلة وفقًا لاستراتيجية التنسيق. الافتراضي هو تنسيق متوافق مع 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=
يمكنك تحديد التنسيقات الخاصة بك حتى تكون متوافقة مع تطبيقات التشفير الأخرى. التنسيق هو كائن له طريقتان - Tringify و Parse - يتحول بين كائنات Cipherparams وسلاسل النص المشفر.
إليك كيف يمكنك كتابة تنسيق 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();
مع openssl
تشفير مع openssl:
openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64
فك التشفير مع cryptoes:
const decrypted = CryptoES.AES.decrypt(openSSLEncrypted, "Secret Passphrase");
يمكن أن يتحول Cryptoes من تنسيقات الترميز مثل BASE64 أو LATIN1 أو HEX إلى كائنات WordArray و VICA بالعكس.
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 تدوين ArrayBuffer أو typedarray حتى يمكن أن تنطبق خوارزف Cryptoes:
const words = CryptoES.lib.WordArray.create(new ArrayBuffer(8));
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
ملاحظة : لم يستطع ArrayBuffer نقله مباشرة إلى الخوارزمية ، يجب عليك تغييرها إلى WordArray أولاً.
مع هذا ، سيكون تشفير الملفات أسهل:
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')
...
};
تغيير السجل
إعادة إنشاء التشفير في ecmascript