Node ใช้การเข้ารหัสและถอดรหัสการส่งข้อมูลอย่างไร บทความต่อไปนี้จะแนะนำให้คุณทราบว่า Node.js ใช้การเข้ารหัสและการถอดรหัสของการส่งข้อมูลส่วนหน้าและส่วนหลังอย่างไร ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ!
หลักสูตรแนะนำ Node.js ฉบับย่อ: เข้าเรียนเพื่อเรียนรู้
ในระหว่างกระบวนการสื่อสารส่วนหน้าและส่วนหลัง ข้อมูลที่ละเอียดอ่อนบางอย่าง โดยเฉพาะบัญชีและรหัสผ่านของผู้ใช้ จำเป็นต้องได้รับการเข้ารหัสเพื่อการส่งผ่าน วิธีเลือกวิธีการเข้ารหัสก็เป็นศาสตร์เช่นกัน แต่ไม่จำเป็นต้องไปไกลเกินไป ที่นี่. โดยทั่วไปแล้ว การเข้ารหัสข้อมูลการส่งข้อมูลที่ใช้กันมากที่สุดในสถาปัตยกรรม B/S คือการเข้ารหัส RSA แนวคิดหลักคือ การเข้ารหัสคีย์สาธารณะและการถอดรหัสคีย์ส่วนตัว กุญแจสาธารณะสามารถเข้าใจได้ว่าเป็นกุญแจที่สามารถทำให้เป็นสาธารณะได้ เซิร์ฟเวอร์จะส่งกุญแจสาธารณะไปยังไคลเอนต์ ไคลเอนต์ใช้กุญแจสาธารณะเพื่อเข้ารหัสและส่งข้อมูล เซิร์ฟเวอร์ได้รับข้อความจากไคลเอนต์แล้วใช้งาน คีย์ส่วนตัวที่จับคู่ของตัวเอง ถอดรหัสเพื่อรับข้อมูลต้นฉบับ
กระบวนการทั่วไปแสดงในรูปด้านล่าง:
มี โมดูลหลัก ใน Nodejs - crypto
ซึ่งมี API ที่เกี่ยวข้องกับการเข้ารหัสและถอดรหัสต่างๆ ตัวอย่างต่อไปนี้เขียนขึ้นตามเวอร์ชัน [email protected]
const crypto = ต้องการ ('crypto'); - * สร้างคู่คีย์สาธารณะและส่วนตัว RSA * @return {*} publicKey: รหัสสาธารณะ; privateKey: รหัสส่วนตัว */ ฟังก์ชั่น genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { โมดูลัสความยาว: 4096, การเข้ารหัสกุญแจสาธารณะ: { ประเภท: 'pkcs1', รูปแบบ: 'pem', - การเข้ารหัสคีย์ส่วนตัว: { ประเภท: 'pkcs1', รูปแบบ: 'pem', - - กลับ { publicKey, privateKey }; - //พิมพ์คู่คีย์สาธารณะและคีย์ส่วนตัวที่สร้างขึ้น console.log(genRSAKeyPaire());
ตัวอย่างผลลัพธ์จะเป็นดังนี้:
(บางส่วนของคีย์สาธารณะและส่วนตัวตัวอย่างถูกลบแล้ว โปรดอย่าใช้สำหรับการทดลอง)
- publicKey: '----- เริ่มต้นคีย์สาธารณะ RSA ----- n' + 'MIICCgKCAgEAsitohTu9Jf2h+NPV4tNfFhPrlbStzXNM8wSEcskwtpwi6aZfgQC7n' + '/A7M1hN8Zk8WgiZjy05AHinWPvXo70OWj8TminIAjB2wh0nDqm+IQqN7r20uzeJmn' + 'GBf1KusGemChEiFwiad1h/OB9z9LC8zMYR/G+XAbFfcv8MxAMI9mgmS8t5+xeYm6n' + 'EMiCQkQjfqpErhW3oESj8hrdJdOZbiK3l0TgYLyjZRQu6pHzFkmd9We3BY1qcXo1n' + '2BtNKvqoH9QDJItsb3S9v2mOGl1rbItKlDrqYCdGY4iyXVIfagNWHraVzHqH/เทอร์n' + 'X+hOmLOwu+Npkz+oEDmnUq1UGY181PBGiNwHVodXx+DF5ckj/bGIxFG2nSiNe3dOn' + 'WLxV3+W8Af0006Oe+fRo1D7xt5SK5AipCpylKKYdyuP3MJ5dpPu7GMICwj20Ndnun' + 'cDJJ2HH9kZAKz6/r62S7ALLuFSecuZr0Dqc6SrJs43zBTpS/hSI33r01ste6Zel8n' + 'uRZKW/4FhUg8gW1KCM+Mp1MaZufOurCDc1Iec0SI71Tteg52BTpfb8cQ9Z1h0xWRn' + 'FdbmLMLuJkIi5oG2+FLAqlGknik0AxXpnlivSOW5Q+eLOh0DjQxxU2sCAwEAAQ==n' + '-----สิ้นสุดคีย์สาธารณะ RSA-----n', privateKey: '----- เริ่มต้นคีย์ส่วนตัว RSA ----- n' + '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' + '-----สิ้นสุดคีย์ส่วนตัว RSA-----n' -
2. การเข้ารหัสคีย์สาธารณะ
ขึ้นอยู่กับคู่คีย์สาธารณะและส่วนตัว คีย์สาธารณะจะถูกใช้สำหรับการเข้ารหัส โค้ดตัวอย่างจะเป็นดังนี้:
const crypto = ต้องการ ('crypto'); - * สร้างคู่คีย์สาธารณะและคีย์ส่วนตัว * @return {*} publicKey: คีย์สาธารณะ; privateKey: คีย์ส่วนตัว */ ฟังก์ชั่น genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { โมดูลัสความยาว: 4096, การเข้ารหัสกุญแจสาธารณะ: { ประเภท: 'pkcs1', รูปแบบ: 'pem', - การเข้ารหัสคีย์ส่วนตัว: { ประเภท: 'pkcs1', รูปแบบ: 'pem', - - กลับ { publicKey, privateKey }; - const { publicKey } = genRSAKeyPaire(); - * ใช้กุญแจสาธารณะสำหรับการเข้ารหัส * ข้อมูล @param {String} * @param {สตริง} publicKey * @return {String} ไซเฟอร์เท็กซ์ที่เข้ารหัส */ ฟังก์ชั่น publicKeyEncrypt (ข้อมูล, publicKey) { กลับ crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64') - รายการ const = { ชื่อ: 'จางซาน' รหัสผ่าน: '123456' - // แปลงข้อมูลเป็นรูปแบบสตริง ทำการเข้ารหัสคีย์สาธารณะ และพิมพ์ console.log(publicKeyEncrypt(JSON.stringify(entry), publicKey));
เนื้อหาเอาต์พุตอยู่ในรูปแบบต่อไปนี้:
(ข้อมูลถูกลบแล้ว)
Ri0p8QFmnYe8Xo36DextK242o9pcdL0QFDo6gUxhzjwQD30UFlqJL57na445BebSp1VT1z94emJgrME7xTDzV1tshtmVNtarqCUCzZMF4uYAtZCQLJhCX3708g7lOFksiUvi6MlXCVVOIu2VyFsIS /6DeEWYNirPK6zEBw1e2V2jWoL+63+iGNyhtKFJI1ECGyMmXUWCMicUmgE/JiHJD7YXPKB9+W aB7Wglj5udBdd4fALUp7qIo8TWJZJkLUg5yMbe7kemNWk050Xi1KiEt3s8IAqoRB1qGghTmE/T W +M/jIblSSy3Urle1AYsOFUzh9wV/H+uD+UNdaCvlvfmdV8hTIjjLNy9r/GbuaI5N0TkaX/dk47iUuorZabPoINEnM8lYxcKPvgVJufMfSX5wLxgx60nt4cpz3T2IutO97sdocVbhsiSlpFLpIk88 xd 4=
3. การถอดรหัสคีย์ส่วนตัว
ด้วยการเข้ารหัสข้อความด้วยกุญแจสาธารณะ ให้ใช้รหัสส่วนตัวเพื่อถอดรหัส รหัสจะเป็นดังนี้:
const crypto = ต้องการ ('crypto'); - * สร้างคู่คีย์สาธารณะและคีย์ส่วนตัว * @return {*} publicKey: คีย์สาธารณะ; privateKey: คีย์ส่วนตัว */ ฟังก์ชั่น genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { โมดูลัสความยาว: 4096, การเข้ารหัสกุญแจสาธารณะ: { ประเภท: 'pkcs1', รูปแบบ: 'pem', - การเข้ารหัสคีย์ส่วนตัว: { ประเภท: 'pkcs1', รูปแบบ: 'pem', - - กลับ { publicKey, privateKey }; - const { publicKey, privateKey } = genRSAKeyPaire(); - * ใช้กุญแจสาธารณะสำหรับการเข้ารหัส * ข้อมูล @param {String} * @param {สตริง} publicKey * @return {String} ไซเฟอร์เท็กซ์ที่เข้ารหัส */ ฟังก์ชั่น publicKeyEncrypt (ข้อมูล, publicKey) { กลับ crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64') - รายการ const = { ชื่อ: 'จางซาน' รหัสผ่าน: '123456' - const encryptedData = publicKeyEncrypt(JSON.stringify(รายการ), publicKey); - * ถอดรหัสโดยใช้คีย์ส่วนตัว * @param {String} เข้ารหัสข้อมูล * @param {สตริง} คีย์ส่วนตัว * @return {String} ข้อความธรรมดาที่ถอดรหัสแล้ว */ ฟังก์ชั่น privateKeyDecrypt (ข้อมูลที่เข้ารหัส, privateKey) { กลับ crypto.privateDecrypt(privateKey, Buffer.from(encryptedData, 'base64')).toString(); - const originData = privateKeyDecrypt (ข้อมูลที่เข้ารหัส, privateKey); //พิมพ์ข้อมูลที่ถอดรหัสด้วยคีย์ส่วนตัว console.log(originData);
ผลลัพธ์ที่ได้:
{"ชื่อ": "จางซาน", "รหัสผ่าน": "123456"}
เนื้อหาของข้อมูล entry
ที่เรากำหนดไว้ข้างต้นมีความสอดคล้อง ซึ่งบ่งชี้ว่าการถอดรหัสสำเร็จ แต่การถอดรหัสนั้นเป็นสตริง หากข้อมูลต้นฉบับเป็นวัตถุ อย่าลืมทำการดีซีเรียลไลซ์ข้อมูลนั้นลงในวัตถุ
ในการพัฒนารายวัน เมื่อพูดถึงการสื่อสารส่วนหน้าและส่วนหลัง โดยเฉพาะข้อมูลที่สำคัญ เพื่อป้องกันไม่ให้บุคคลที่สามรับและใช้งาน โดยทั่วไปแล้วจะมีการเข้ารหัสการส่งผ่านการสื่อสาร สิ่งพื้นฐานที่สุดคือการใช้โปรโตคอล https
แต่โปรโตคอล https เพียงอย่างเดียวนั้นไม่เพียงพอ (ง่ายต่อการถูกแย่งชิงและโจมตีโดยคนกลาง) ดังนั้นข้อมูลจะต้องได้รับการเข้ารหัสที่ชั้นแอปพลิเคชันเพื่อป้องกันไม่ให้ผู้อื่นถูกแย่งชิงและใช้งานข้อมูล การใช้การเข้ารหัสแบบอสมมาตรช่วยให้มั่นใจได้ว่าไซเฟอร์เท็กซ์ที่ส่งจะสามารถถอดรหัสได้โดยเซิร์ฟเวอร์ด้วยคีย์ส่วนตัวเท่านั้น จึงช่วยป้องกันไม่ให้ไซเฟอร์เท็กซ์ถูกเข้ารหัส ถอดรหัสและใช้งานโดยฝ่ายที่ไม่เกี่ยวข้องอื่น ๆ ไม่มีการรักษาความปลอดภัยที่สมบูรณ์ในด้านอินเทอร์เน็ต ทางออกเดียวในระยะยาวคือการปรับปรุงความตระหนักรู้ด้านความปลอดภัยของคุณอย่างต่อเนื่องและเพิ่มพูนทักษะด้านความปลอดภัยของคุณ