Node는 데이터 전송의 암호화 및 복호화를 어떻게 구현합니까? 다음 기사에서는 Node.js가 프런트엔드 및 백엔드 데이터 전송의 암호화 및 암호 해독을 구현하는 방법을 소개합니다. 도움이 되기를 바랍니다.
Node.js 빠른 소개 과정: 배우려면 입력하세요.
프런트엔드 및 백엔드 통신 과정에서 일부 민감한 정보, 특히 사용자 계정과 비밀번호는 전송을 위해 암호화되어야 합니다. 암호화 방법을 선택하는 방법도 과학이지만 너무 멀리 갈 필요는 없습니다. 여기. 일반적으로 B/S 아키텍처에서 가장 일반적으로 사용되는 전송 데이터 암호화는 RSA 암호화이며, 핵심 아이디어는 공개 키 암호화와 개인 키 복호화 입니다. 공개 키는 공개할 수 있는 키로 이해될 수 있습니다. 클라이언트는 공개 키를 사용하여 데이터를 암호화하고 전송합니다. 자신의 페어링된 개인 키를 해독하여 원본 데이터를 가져옵니다.
일반적인 프로세스는 아래 그림에 나와 있습니다.
Nodejs에는 다양한 암호화 및 복호화 관련 API를 제공하는 crypto
라는 핵심 모듈 이 있습니다. 다음 예제는 [email protected]
버전을 기준으로 작성되었습니다.
const crypto = require('암호화'); /** * RSA 공개 및 개인 키 쌍 생성 * @return {*} publicKey: 공개 키: 개인 키 */ 함수 genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { 모듈러스길이: 4096, 공개키인코딩: { 유형: 'pkcs1', 형식: 'pem', }, privateKeyEncoding: { 유형: 'pkcs1', 형식: 'pem', }, }); return { 공개키, 비공개키 }; } //생성된 공개 키와 개인 키 쌍을 인쇄합니다. console.log(genRSAKeyPaire());
예제 출력은 다음과 같습니다.
(샘플 공개키와 개인키 중 일부가 삭제되었으니 실험용으로 사용하지 마시기 바랍니다.)
{ publicKey: '-----RSA 공개 키 시작-----n' + 'MIICCgKCageEAsitohTu9Jf2h+NPV4tNfFhPrlbStzXNM8wSEcskwtpwi6aZfgQC7n' + '/A7M1hN8Zk8WgiZjy05AHinWPvXo70OWj8TminIAjB2wh0nDqm+IQqN7r20uzeJmn' + 'GBf1KusGemChEiFwiad1h/OB9z9LC8zMYR/G+XAbFfcv8MxAMI9mgmS8t5+xeYm6n' + 'EMiCQkQjfqpErhW3oESj8hrdJdOZbiK3l0TgYLyjZRQu6pHzFkmd9We3BY1qcXo1n' + '2BtNKvqoH9QDJitsb3S9v2mOGl1rbItKlDrqYCdGY4iyXVIfagNWHraVzHqH/tern' + '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 = require('암호화'); /** * 공개 키와 개인 키 쌍 생성 * @return {*} publicKey: 공개 키: 개인 키 */ 함수 genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { 모듈러스길이: 4096, 공개키인코딩: { 유형: 'pkcs1', 형식: 'pem', }, privateKeyEncoding: { 유형: 'pkcs1', 형식: 'pem', }, }); return { 공개키, 비공개키 }; } const { publicKey } = genRSAKeyPaire(); /** * 암호화를 위해 공개 키 사용 * @param {String} 데이터 * @param {String} 공개키 * @return {String} 암호화된 암호문 */ 함수 publicKeyEncrypt(데이터, 공개키) { return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64') } const 항목 = { 이름: '장산', 비밀번호: '123456' }; // 데이터를 문자열 형식으로 변환하고 공개 키 암호화를 수행한 후 인쇄합니다. console.log(publicKeyEncrypt(JSON.stringify(entry), publicKey));
출력 내용은 다음 형식입니다.
(데이터가 삭제되었습니다)
Ri0p8QFmnYe8Xo36DextK242o9pcdL0QFDo6gUxhzjwQD30UFlqJL57na445BebSp1VT1z94emJgrME7xTDzV1tshtmVNtarqCUCzZMF4uYAtZCQLJhCX3708g7lOFksiUvi6MlXCVVOIu2VyFs IS /6DeEWYNirPK6zEBw1e2V2jWoL+63+iGNyhtKFJI1ECGyMmXUWCMicUmgE/JiHJD7YXPKB9+WaB7Wglj5udBdd4fALUp7qIo8TWJZJkLUg5yMbe7kemNWk050Xi1KiEt3s8IAqoRB1qGghTmE /TW +M/jIblSSy3Urle1AYsOFUzh9wV/H+uD+UNDaCvlvfmdV8hTIjjLNy9r/GbuaI5N0TkaX/dk47iUuorZabPoINEnM8lYxcKPvgVJufMfSX5wLxgx60nt4cpz3T2IutO97sdocVbhsiSlpFLpIk88 xd4=
3. 개인키 복호화
공개키로 암호화된 암호문을 개인키를 이용해 복호화하면 다음과 같다.
const crypto = require('암호화'); /** * 공개 키와 개인 키 쌍 생성 * @return {*} publicKey: 공개 키: 개인 키 */ 함수 genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { 모듈러스길이: 4096, 공개키인코딩: { 유형: 'pkcs1', 형식: 'pem', }, privateKeyEncoding: { 유형: 'pkcs1', 형식: 'pem', }, }); return { 공개키, 비공개키 }; } const { publicKey, privateKey } = genRSAKeyPaire(); /** * 암호화를 위해 공개 키 사용 * @param {String} 데이터 * @param {String} 공개키 * @return {String} 암호화된 암호문 */ 함수 publicKeyEncrypt(데이터, 공개키) { return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64') } const 항목 = { 이름: '장산', 비밀번호: '123456' }; const cryptoData = publicKeyEncrypt(JSON.stringify(entry), publicKey); /** * 개인 키를 사용하여 복호화 * @param {String} encryptedData * @param {String} privateKey * @return {String} 복호화된 일반 텍스트 */ 함수 privateKeyDecrypt(encryptedData, privateKey) { return crypto.privateDecrypt(privateKey, Buffer.from(encryptedData, 'base64')).toString(); } const OriginData = privateKeyDecrypt(encryptedData, privateKey); //개인키로 복호화된 데이터를 출력한다. console.log(originData);
출력 결과:
{"이름":"장산","비밀번호":"123456"}
위에서 정의한 entry
데이터의 내용은 일관적이므로 해독이 성공했음을 나타냅니다. 그러나 원본 데이터가 객체인 경우 객체로 역직렬화하는 것을 잊지 마세요.
일상적인 개발에서 프론트엔드와 백엔드 통신, 특히 중요한 정보에 대해서는 제3자가 이를 획득하고 사용하는 것을 방지하기 위해 일반적으로 통신 전송 암호화가 수행됩니다. 가장 기본적인 것은 https
프로토콜을 사용하는 것입니다. , 그러나 https 프로토콜만으로는 충분하지 않습니다(중간자에게 납치 및 공격을 받기 쉽습니다). 따라서 데이터가 도용되어 다른 사람에 의해 사용되는 것을 방지하려면 데이터를 애플리케이션 계층에서 암호화해야 합니다. 비대칭 암호화를 사용하면 전송된 암호문을 개인 키를 사용하는 서버에서만 해독할 수 있으므로 암호문이 유출되는 것을 방지할 수 있습니다. 관련되지 않은 다른 당사자가 해독하여 사용합니다. 인터넷 분야에는 절대적인 보안이 없습니다. 유일한 장기적인 해결책은 보안 인식을 지속적으로 향상시키고 보안 기술을 향상시키는 것입니다.