🌟
【NodeJS】CryptoJS|共通鍵で暗号化→URLクエリパラメータ経由→共通鍵で復号化
まえがき
crypto-jsで文字列を暗号化。URL経由で受け手に連携した後、復号化する。
ポイント
✅復号化できる=信頼された元からリクエストされたことの証明。
✅共通鍵は互いのNodeJSサーバの環境変数で管理。
✅暗号化をよりセキュアなものにするための「初期化ベクトル」。
✅パラメータを①Base64エンコード②URLSearchParams でURLセーフにする。
Raw文字列
↓ Base64エンコード↓
Base64文字列
↓ Base64内の特殊文字(`+`,`=`,`/`)をエスケープ処理) by URLSearchParams
URLセーフな文字列
ソースコード
express定義部分は割愛し、暗号化/復号化の処理部分のみ記載します。
暗号化する側
const queryString = require('query-string');
const CryptoJS = require('crypto-js');
const btoa = require('btoa');
// 1. 共通鍵 用意(process.env経由で環境変数参照するのがGood)
const key = CryptoJS.enc.Utf8.parse(`commonkeyissecret`);
// 2. 初期化ベクトル用意
const iv = CryptoJS.lib.WordArray.random(16);
// 3. パラメータを暗号化
const encrypted = CryptoJS.AES.encrypt('暗号化したい情報', key, { iv });
// 4. 【暗号化パラメータ文字列,初期化ベクトル】
const base64Encrypted = btoa(encrypted.toString());
const base64Iv = encrypted.iv.toString(CryptoJS.enc.Base64);
const concatParams = `${base64Encrypted},${base64Iv}`;
// 5. queryStringでパラメータ文字列作成
const queryStrings = queryString.stringify({ param: concatParams});
復号化する側
// 6. queryStringでパラメータ取得
const urlParameters2 = queryString.parse(urlParameters1);
const base64Encrypted2 = urlParameters2.param.split(",")[0];
const base64Iv2 = urlParameters2.param.split(",")[1];
console.log(atob(base64Encrypted2));
console.log(atob(base64Iv2));
Special Thanks
JavaScriptでCryptoJSを使って、AESの暗号化と復号を行う
2022/10/26 追記 query-string/URLSearchParamsでURLセーフにする
BASE64文字列に含まれる特殊文字(+
,=
,/
)は、query-string/URLSearchParamsでエスケープ処理されて、URLセーフとなる。
query-string
const querystring = require('query-string');
const base64UrlEncodedParams = "aaaaaaaaa+ddddddddddddd/ddddddddd===";
const before = querystring.stringify({ param: base64UrlEncodedParams });
const after = querystring.parse(before);
console.log(before);
// param=aaaaaaaaa%2Bddddddddddddd%2Fddddddddd%3D%3D%3D
console.log(after);
// [Object: null prototype] {
// param: 'aaaaaaaaa+ddddddddddddd/ddddddddd==='
// }
URLSearchParams
const params = new URLSearchParams([["param", "AA//BB++CC=="]]);
console.log(params.toString()); // param=AA%2F%2FBB%2B%2BCC%3D%3D
Discussion