search
LoginSignup
3

More than 3 years have passed since last update.

posted at

updated at

便利ページ:Javascriptで暗号化など追加

便利ページ: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' )

以上

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3