🌟

【NodeJS】CryptoJS|共通鍵で暗号化→URLクエリパラメータ経由→共通鍵で復号化

2022/10/21に公開

まえがき

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の暗号化と復号を行う

初期化ベクトルとは?暗号化で知っておくべき基礎知識を解説!

BASE64URL Encodingのすすめ

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