Google Authenticatorのトークンをフォームに自動で入力し、ついでに自動でログインしてくれるChrome拡張機能を自作した

IT

Google AuthenticatorをiPhoneで開くのが面倒。
PCのツールからブラウザのフォームにコピペするのも面倒。
勝手に入力して、ついでにログインしてほしい。
そんな俺だけのためにGoogle Chrome拡張機能を自作した。

自作したChrome拡張機能

ファイル構成

適当なディレクトリ
├ js
│ ├ jsrsasign-all-min.js
│ ├ totp.js
│ └ autofill.js
└ manifest.json

各ファイルの内容

jsrsasign-all-min.js

暗号系のライブラリ。こちらからダウンロードする。
今回ダウンロードしたものは10.1.4というバージョンだった。

totp.js

トークンの計算処理。
株式会社セシオスさんのブログで公開されていたコードをありがたく拝借し、一部改変した。

// 共有シークレット Google AuthenticatorはBase32文字列、SlinkPassはBase64文字列。
// ワンタイムパスワードの時間間隔 Google Authenticatorは30秒、SlinkPassは60秒。
// ワンタイムパスワードの桁数     Google Authenticatorは6桁、 SlinkPassは8桁。
function gauth(base32) {
    let secret = base32tohex(base32);
    return totp(secret, 6, 30);
}

// function slinkpass(base64) {
//     let secret = b64tohex(base64);
//     return totp(secret, 8, 60);
// }

function totp(secret, digits, period) {
    // 現在のエポック時刻を基にカウンタ計算
    let epoch  = new Date().getTime() / 1000;
    // カウンタとシークレットを十六進に変換、8バイトとのカウンター値を取得
    let count = parseInt(epoch / period);
    let arrCnt = new Array(8);
    for (let i = arrCnt.length - 1; i >= 0; i--) {
        arrCnt[i] = dec2hex(count & 0xff);
        count >>= 8;
    }
    let hexCnt = CryptoJS.enc.Hex.parse(arrCnt.join(''));
    let hexSrt = CryptoJS.enc.Hex.parse(secret);
    // HMAC-SHA1でハッシュ値を生成
    let hexHmac = CryptoJS.HmacSHA1(hexCnt, hexSrt).toString(CryptoJS.enc.Hex);
    // ハッシュ値の20バイト目の下位4ビットを取り出しオフセット値とする
    let arrHmac = [];
    for (let i = 0; i < hexHmac.length; i = i + 2) {
        arrHmac.push(hex2dec(hexHmac.substr(i, 2)));
    }
    let offset = arrHmac[arrHmac.length - 1] & 0xf;
    // オフセット値をハッシュ値のバイト列に当てはめ、そこから31ビット取り出す
    let truncate = hex2dec(hexHmac.substr(offset * 2, 8)) & 0x7fffffff;
    // 出力する桁数に合わせて切り詰める
    let otp = truncate % Math.pow(10, digits);
    // 桁数足りなかったら、前頭に0を補足してさい。
    while (otp.toString().length < digits) {
        otp = '0' + otp;
    }
    return otp;
}
// ライブラリ
function hex2dec(h) { return parseInt(h, 16); }
function dec2hex(d) { return ('0' + (Number(d).toString(16))).slice(-2); }
function leftpad(str, len, pad) {
    if (len + 1 >= str.length) {
        str = Array(len + 1 - str.length).join(pad) + str;
    }
    return str;
}
function base32tohex(base32) {
    const base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    let bits = "";
    let hex = "";
    for (let i = 0; i < base32.length; i++) {
        let val = base32chars.indexOf(base32.charAt(i).toUpperCase());
        bits += leftpad(val.toString(2), 5, '0');
    }
    for (let i = 0; i+4 <= bits.length; i+=4) {
        const chunk = bits.substr(i, 4);
        hex = hex + parseInt(chunk, 2).toString(16) ;
    }
    return hex;
}
autofill.js

ログイン画面でフォームに値をセットしたりログインする処理。
各自の環境に応じて適当に書くこと。こんなかんじ。

// フォームに値をセット
document.forms[0].username.value="{ユーザ名}"
document.forms[0].password.value="{PINコード}" + gauth("{32桁の共有鍵}");
// ログイン実行
if(confirm("ログインします。")){
    document.forms[0].submit();
}
manifest.json

Chrome機能拡張として動かすための定義。
こんな感じ。

{
  "name": "GAuthAutofill",
  "version": "1.0.0",
  "manifest_version": 2,
  "description": "GoogleAuthenticator自動入力",
  "content_scripts": [{
    "matches": ["https://{処理対象のログイン画面のURLを埋める}"],
    "js": [
      "js/jsrsasign-all-min.js",
      "js/totp.js",
      "js/autofill.js"
    ]
  }]
}

Chrome拡張機能として登録する

  1. Chromeの右上の「︙(点が縦に3つ並んだアイコン)」→「その他のツール」→「拡張機能」を選択する。もしくはアドレスバーに「chrome://extensions」と入力して開く。
  2. 拡張機能画面の右上の「デベロッパーモード」をONにする。
  3. 「パッケージ化されていない拡張機能を読み込む」から、上記で作成したディレクトリを指定して読み込む。

Chrome拡張機能を削除する

削除したくなったら、登録と同じ手順で拡張機能画面を開いて、拡張機能の「削除」ボタンを押下すればよい。


【参考サイト】

ワンタイムパスワードJavascriptで生成
ワンタイムパスワードの生成 JSRSASIGNライブラリを利用してjavascriptで Google Aut…
jsrsasign - cryptography library in JavaScript
opensource free pure JavaScript cryptographic library supports RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate,...
IT
広告
一郎くんどっとこむ