ノードはデータ送信の暗号化と復号化をどのように実装しますか?次の記事では、Node.js がフロントエンドとバックエンドのデータ送信の暗号化と復号化を実装する方法を紹介します。お役に立てば幸いです。
Node.js クイック入門コース: 学習するために入力してください
フロントエンドとバックエンドの通信プロセス中に、一部の機密情報、特にユーザーのアカウントとパスワードを送信のために暗号化する必要があります。暗号化方法を選択する方法も重要ですが、過度にこだわる必要はありません。ここ。 一般に、B/S アーキテクチャで最も一般的に使用される送信データ暗号化は、公開鍵暗号化と秘密鍵復号化が中心的な考え方です。 公開キーは、公開できるキーとして理解できます。サーバーは、公開キーを使用してデータを暗号化して送信し、その暗号文を使用します。独自のペアの秘密キーを復号化して元のデータを取得します。
一般的なプロセスを次の図に示します。
Nodejs にはコア モジュール- crypto
があり、さまざまな暗号化と復号化関連の API を提供します。次の例は、 [email protected]
バージョンに基づいて記述されています。
const crypto = require('crypto'); /** * RSA 公開キーと秘密キーのペアを生成します * @return {*} publicKey: 公開キー: privateKey: 秘密キー */ 関数 genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { 係数長さ: 4096、 publicKeyEncoding: { タイプ: 'pkcs1'、 形式: 'pem'、 }、 privateKeyEncoding: { タイプ: 'pkcs1'、 形式: 'pem'、 }、 }); 戻り値 { publicKey, privateKey }; } //生成された公開キーと秘密キーのペアを出力します console.log(genRSAKeyPaire());
出力例は次のとおりです。
(サンプルの公開鍵と秘密鍵の一部を削除していますので、実験には使用しないでください)
{ publicKey: '-----RSA 公開キーの開始-----n' + 'MIICCgKCAgEAsitohTu9Jf2h+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('crypto'); /** * 公開キーと秘密キーのペアを生成します * @return {*} publicKey: 公開キー: privateKey: 秘密キー */ 関数 genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { 係数長さ: 4096、 publicKeyEncoding: { タイプ: 'pkcs1'、 形式: 'pem'、 }、 privateKeyEncoding: { タイプ: 'pkcs1'、 形式: 'pem'、 }、 }); 戻り値 { publicKey, privateKey }; } const { publicKey } = genRSAKeyPaire(); /** * 暗号化には公開キーを使用 * @param {String} データ * @param {文字列} publicKey * @return {String} で暗号化された暗号文 */ 関数 publicKeyEncrypt(data, publicKey) { return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64') } const エントリ = { 名前:「張三」、 パスワード: '123456' }; // データを文字列形式に変換し、公開キー暗号化を実行して出力します console.log(publicKeyEncrypt(JSON.stringify(entry), publicKey));
出力内容は次の形式です。
(データは削除されました)
Ri0p8QFmnYe8Xo36DextK242o9pcdL0QFDo6gUxhzjwQD30UFlqJL57na445BebSp1VT1z94emJgrME7xTDzV1tshtmVNtarqCUCzZMF4uYAtZCQLJhCX3708g7lOFksiUvi6MlXCVVOIu2Vy FsIS /6DeEWYNirPK6zEBw1e2V2jWoL+63+iGNyhtKFJI1ECGyMMXUWCMicUMGE/JiHJD7YXPKB9+WaB7Wglj5udBdd4fALUp7qIo8TWJZJkLUg5yMbe7kemNWk050Xi1KiEt3s8IAqoRB1qGghTmE /TW +M/jIblSSy3Urle1AYsOFUzh9wV/H+uD+UNDaCvlvfmdV8hTIjjLNy9r/GbuaI5N0TkaX/dk47iUuorZabPointenM8lYxcKPvgVJufMfSX5wLxgx60nt4cpz3T2IutO97sdocVbhsiSlpFLpik8 8×d4=
3. 秘密鍵の復号化
公開鍵で暗号化された暗号文を秘密鍵で復号化するコードは次のとおりです。
const crypto = require('crypto'); /** * 公開キーと秘密キーのペアを生成します * @return {*} publicKey: 公開キー: privateKey: 秘密キー */ 関数 genRSAKeyPaire() { const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { 係数長さ: 4096、 publicKeyEncoding: { タイプ: 'pkcs1'、 形式: 'pem'、 }、 privateKeyEncoding: { タイプ: 'pkcs1'、 形式: 'pem'、 }、 }); 戻り値 { publicKey, privateKey }; } const { publicKey , privateKey } = genRSAKeyPaire(); /** * 暗号化には公開キーを使用 * @param {String} データ * @param {文字列} publicKey * @return {String} で暗号化された暗号文 */ 関数 publicKeyEncrypt(data, publicKey) { return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64') } const エントリ = { 名前:「張三」、 パスワード: '123456' }; const encryptedData = publicKeyEncrypt(JSON.stringify(entry), publicKey); /** * 秘密キーを使用して復号化します * @param {String} encryptedData * @param {文字列} プライベートキー * @return {String} 復号化された平文 */ 関数 privateKeyDecrypt(encryptedData, privateKey) { return crypto.privateDecrypt(privateKey, Buffer.from(encryptedData, 'base64')).toString(); } const OriginData = privateKeyDecrypt(encryptedData, privateKey); //秘密鍵で復号化されたデータを出力します console.log(originData);
出力結果:
{"名前":"張三"、"パスワード":"123456"}
上で定義したentry
データの内容は一貫しており、復号化が成功したことを示していますが、元のデータがオブジェクトである場合は、それをオブジェクトに逆シリアル化することを忘れないでください。
日常の開発において、特に重要な情報であるフロントエンドやバックエンドの通信においては、第三者による取得や利用を防ぐため、通信伝送の暗号化が行われるのが最も基本的なプロトコルであるhttps
プロトコルを使用することが一般的です。 , しかし、https プロトコルだけでは十分ではありません (中間者によって乗っ取られ、攻撃されやすい)。 したがって、データが他人にハイジャックされて使用されるのを防ぐために、データをアプリケーション層で暗号化する必要があります。非対称暗号化を使用すると、送信された暗号文は秘密キーを使用したサーバーのみで復号化できるようになり、暗号文が暗号化されるのを防ぐことができます。復号化され、関係のない他の当事者によって使用されます。 インターネット分野に絶対的なセキュリティはありません。唯一の長期的な解決策は、セキュリティ意識を継続的に向上させ、セキュリティ スキルを向上させることです。