便利ページ:Javascriptでちょっとした便利な機能を作ってみた のシリーズものです。
今回は、WebAuthnを使ったFIDOサーバを立ててみた の実装をしていたところ、何かと便利になりそうなことがありそうだったので、追加してみようと思いました。
- バイナリのBase64エンコード
- Base64URLエンコード
- 文字列のバイト配列変換
- HMAC(SHA256)生成、AES暗号化
毎度の通り、デモページとGitHubです。
GitHub
https://github.com/poruruba/utilities
デモページ
https://poruruba.github.io/utilities/
バイナリのBase64エンコード
画像などのバイナリデータをJSON等で送る場合によく使われているようです。確かに、16進数文字列にするより、サイズ的に効率的ですね。
Webにたくさん転がっていましたので、盲目的に採用させていただきました。
function bufferToBase64(buf) {
if( buf instanceof ArrayBuffer )
buf = new Uint8Array(buf);
if( buf instanceof Uint8Array )
buf = Array.from(buf);
var binstr = buf.map(b => String.fromCharCode(b)).join("");
return btoa(binstr);
}
function base64ToBuffer(b64) {
var binstr = atob(b64);
var buf = new Uint8Array(binstr.length);
Array.from(binstr).forEach((ch, i) => buf[i] = ch.charCodeAt(0));
return buf;
}
Base64URLエンコード
BASE64URLとは、Webにおいて主にバイナリデータの送受で使われているようで、Base64エンコードに対して、Webで扱いやすいように、「+」を「-」に、「/」を「_」に置き換え、パディングも省略されたもののようです。
以下のモジュールを使わせていただきました。
Base64URL-ArrayBuffer
https://github.com/herrjemand/Base64URL-ArrayBuffer
文字列のバイト配列変換
これも、Web上にたくさん情報がありますが、使いたい時にさっと使えるように、便利ツールに追加しました。
var encoder = new TextEncoder('utf-8');
output = encoder.encode('文字列');
var decoder = new TextDecoder('utf-8');
output = decoder.decode(バイト配列);
HMAC(SHA256)生成、AES暗号化
暗号演算には、以下のモジュールを使わせていただきました。
crypto-js
https://github.com/brix/crypto-js
以下に、使い方の説明ページがあったので、すんなり実装できました。
https://cryptojs.gitbook.io/docs/
具体的には、ソースコードを見ていただくとして、なぜ便利ツールに追加したかというと、AWS Cognitoのカスタム認証フローにSECRET_HASHなる仕様で必要だったためです。実装したものの、あまり使う機会がなく、忘れてしまいそうでした。
今回とはちょっと横道にそれますが、こんな感じだそうです。
function makeSecretHash(username, client_id, client_secret){
var hash = CryptoJS.HmacSHA256(username + client_id, client_secret);
var result = wordarray_to_uint8array(hash);
return bufferToBase64(result);
}
var secretHash = makeSecretHash(this.username, UserPoolClientId, UserPoolClientSecret);
var params = {
AuthFlow: 'CUSTOM_AUTH',
ClientId: UserPoolClientId,
AuthParameters: {
'USERNAME' : this.username,
'SECRET_HASH' : secretHash
}
};
do_post_aws(CognitoUrl, params, 'AWSCognitoIdentityProviderService.InitiateAuth' )
以上