日本国内のシステムでは、いまだに文字コードとしてSJIS(シフトJIS, Shift JIS)が使われているものがある。電文の送受信にあたり、整合性の確認のためにハッシュ値を付与する場合、暗号化ライブラリで文字コードを指定してハッシュを生成する必要がある。
- 参考
- 環境情報
- TypeScript
- SJISバイト列のbase64をcrypto-jsに渡すのがポイント
- JavaScript
- まとめ - Node.jsでSJIS文字列をSHA1ハッシュする
- 関連情報
参考
実装したい内容はこちらに近いのですが、質問が伝わらず回答が得られていない。
環境情報
Node.jsバージョン
- Node.js:
v16.17.0
- npm:
8.19.2
- TypeScript:
4.8.3
使用ライブラリ
- crypto-js:
4.1.1
- iconv-lite:
0.6.3
TypeScript
npm install
npm install crypto-js npm install --save-dev @types/crypto-js npm install iconv-lite
sha1.ts
ポイントは後述。
import { SHA1, enc } from "crypto-js"; import * as iconv from "iconv-lite"; console.log(iconv.encode("testテスト", "Shift_JIS")); console.log(iconv.encode("testテスト", "Shift_JIS").toString("base64")); const sha1 : string = SHA1(enc.Base64.parse(iconv.encode("testテスト", "Shift_JIS").toString("base64"))).toString(); console.log("sha1:" +sha1);
実行結果
$ ts-node ./sha1.ts <Buffer 74 65 73 74 83 65 83 58 83 67> dGVzdINlg1iDZw== sha1:fb71edbbaeaf718cd7f7734362a7ee14f30f5114
sha1ハッシュが得られた。
SJISバイト列のbase64をcrypto-jsに渡すのがポイント
(method) CipherHelper.encrypt(message: string | CryptoJS.lib.WordArray, key: string | CryptoJS.lib.WordArray, cfg?: CipherOption | undefined): CryptoJS.lib.CipherParams
対象文字列はstring, CryptoJS.lib.WordArrayのいずれかとなるが、stringを渡すとUTF-8で扱われてしまうため、CryptoJS.lib.WordArrayを使用する。CryptoJS.lib.WordArrayを生成するとき、enc.xxx.parseでSJISは直接扱えないようなので、iconvでSJISバイト列をbase64にしたものを渡す。
結果検証
SJIS
SJIS SHA1ハッシュの整合性の検証として、こちらを使用させていただきました。
生成されるハッシュ値が一致している。
UTF-8
UTF-8の場合はopenssl
コマンドで検証できる。
const sha1_utf : string = SHA1(enc.Utf8.parse("testテスト")).toString(); console.log("sha1-utf:" +sha1_utf); --- sha1-utf:bdafcf6b7484bdc7b836a669b8548b9eb5ae665b
$ echo -n "testテスト" | openssl sha1 bdafcf6b7484bdc7b836a669b8548b9eb5ae665b
JavaScript
npm install
npm install crypto-js npm install iconv-lite
sha1.js
基本は同上。import
をrequire
に置き換え、変数の型宣言を削除する。
var CryptoJS = require("crypto-js"); var SHA1 = CryptoJS.SHA1; var enc = CryptoJS.enc; var iconv = require("iconv-lite"); console.log(iconv.encode("testテスト", "Shift_JIS")); console.log(iconv.encode("testテスト", "Shift_JIS").toString("base64")); const sha1 = SHA1(enc.Base64.parse(iconv.encode("testテスト", "Shift_JIS").toString("base64"))).toString(); console.log("sha1:" +sha1);
実行結果
$ node ./sha1.js <Buffer 74 65 73 74 83 65 83 58 83 67> dGVzdINlg1iDZw== sha1:fb71edbbaeaf718cd7f7734362a7ee14f30f5114
結果は同上。
まとめ - Node.jsでSJIS文字列をSHA1ハッシュする
crypto-jsとiconv-liteを組み合わせ、SJISバイト列のbase64を渡すことで、SJIS文字列をSHA1ハッシュ化することができた。