ห้องสมุดอัลกอริทึมการเข้ารหัสที่เข้ากันได้กับ 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");
sha-1
ฟังก์ชั่น SHA Hash ได้รับการออกแบบโดย National Security Agency (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 ในบริบทของสตริงมันจะถูกแปลงเป็นสตริง HEX โดยอัตโนมัติ
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();
รหัสการรับรองความถูกต้องข้อความ Keyed-Hash (HMAC) เป็นกลไกสำหรับการตรวจสอบข้อความโดยใช้ฟังก์ชันแฮช cryptographic
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 1/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 ให้อัตราการเข้ารหัสที่ดีในซอฟต์แวร์และไม่พบ cryptanalysis ที่มีประสิทธิภาพของมันจนถึงปัจจุบัน อย่างไรก็ตามมาตรฐานการเข้ารหัสขั้นสูง (AES) ได้รับความสนใจมากขึ้นและ Schneier แนะนำ twofish สำหรับการใช้งานที่ทันสมัย
Schneier ออกแบบ blowfish เป็นอัลกอริทึมอเนกประสงค์ทั่วไปซึ่งมีวัตถุประสงค์เพื่อเป็นทางเลือกสำหรับ Des อายุและปราศจากปัญหาและข้อ จำกัด ที่เกี่ยวข้องกับอัลกอริทึมอื่น ๆ ในช่วงเวลาที่ Blowfish ได้รับการปล่อยตัวการออกแบบอื่น ๆ อีกมากมายเป็นกรรมสิทธิ์ที่ถูกบังคับใช้โดยสิทธิบัตรหรือเป็นความลับเชิงพาณิชย์หรือรัฐบาล Schneier ได้กล่าวว่า "ปลาพองไม่ได้รับการยอมรับและจะยังคงอยู่ในทุกประเทศอัลกอริทึมจะถูกวางไว้ในโดเมนสาธารณะและทุกคนสามารถใช้งานได้อย่างอิสระ"
คุณสมบัติที่โดดเด่นของการออกแบบรวมถึงกล่อง 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 จริง
สำหรับ ciphertext อัลกอริทึมการเข้ารหัสจะยอมรับสตริงหรืออินสแตนซ์ของ cryptoes.lib.cipherparams วัตถุ CipherParams แสดงถึงการรวบรวมพารามิเตอร์เช่น IV, เกลือและ ciphertext แบบดิบเอง เมื่อคุณผ่านสตริงมันจะถูกแปลงเป็นวัตถุ CipherParams โดยอัตโนมัติตามกลยุทธ์รูปแบบที่กำหนดค่าได้
ข้อความธรรมดาที่คุณได้รับหลังจากถอดรหัสเป็นวัตถุ WordArray ดูผลลัพธ์ของ Hashers สำหรับรายละเอียดเพิ่มเติม
ciphertext ที่คุณได้รับหลังจากการเข้ารหัสยังไม่ได้เป็นสตริง มันเป็นวัตถุ 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=
คุณสามารถกำหนดรูปแบบของคุณเองเพื่อให้เข้ากันได้กับการใช้งาน crypto อื่น ๆ รูปแบบเป็นวัตถุที่มีสองวิธีคือสไตรทริงก์และแยกวิเคราะห์ - แปลงระหว่างวัตถุ cipherparams และสตริง ciphertext
นี่คือวิธีที่คุณจะเขียน Formatter 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 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 สามารถรับ 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')
...
};
เปลี่ยนบันทึก
refactoring cryptojs ใน ecmascript ที่ทันสมัย