
現在、2FA、VPN への接続などに Google Authenticator を使用しています。OSX ボックスで 6 桁のコードを取得できるかどうかを確認したかったのですが、何らかの理由でoathtool
Authenticator と同じ値が返されません。また、Authenticator コードは機能しますが、oathtool
1 つは機能しません。
興味深いことに、iOSシミュレーターでも試してみました。https://github.com/mattrubin/認証子同じシステム上で、生成されるコードはoathtool
Authenticator と一致しますが、Authenticator とは一致しません。
これはおそらく時間同期の問題ではないかと思いましたが、OSX の時間を手動で同期した後、コードは同じでした。TOTP アルゴリズムに一致しないデフォルトのパラメータがあるのではないかと思っていますが、それが何なのかはわかりません。
コマンドoathtool
の出力は次のようになります
% oathtool --verbose --base32 --totp "$SECRET"
Hex secret: ...
Base32 secret: ...
Digits: 6
Window size: 0
Step size (seconds): 30
Start time: 1970-01-01 00:00:00 UTC (0)
Current time: 2016-10-20 22:27:22 UTC (1477002442)
Counter: 0x2EF3E06 (49233414)
(注:$SECRET
上記は、Authenticator が使用した QR コードを生成するために使用された値と同じです。)
これらが同意しない理由は何でしょうか?
アップデート
私はシステム時間の前後30秒の時間をいじってみました
oathtool --now "$(perl -e'use DateTime; print DateTime->now()->subtract(seconds=>30)->strftime( "%Y-%m-%d %H:%M:%S %Z" )')" -b --totp $SECRET -w 20|sort
上記のperlは次の形式で時間を生成します。
2016-10-20 23:36:15 UTC
また、毎回 20 個の数字を出力しましたが、そのどれもが Authenticator にある数字と一致しないようです。
答え1
「Google Authenticator oathtool」を検索するとここにたどり着きますが、回答の一部はコメントにあるので、利便性と完全性のために...
oathtool
Google Authenticatorは、RFC 6238 TOTPTOTP は HMAC を使用して 6 桁の出力を生成します。公式の Android クライアントはもはやオープン ソースではありませんが、それは TOTP の実装が変更されたか、「秘密」になっているからではありません。
HMAC には、数値とシークレットの 2 つの入力があります。TOTP では、数値はエポックからの時間間隔の数で、oathtool
と GA の両方のデフォルトは 30 秒間隔 (「時間ステップ」サイズ) と 1970-01-01 00:00:00 UTC です。明確に言えば、oathtool
パラメータが一致する限り、 と GA は一致します。つまり、エポックと時間は十分に近く、時間ステップとシークレットは一致している必要があります。
必要に応じて (たとえば、一部のハードウェア TOTP トークンは 60 秒間隔を使用します)、間隔のサイズを設定するために使用でき-s
、オフセット/ドリフトに対応するために、oathtool が「現在」と考えるものを上書きできます (またはエポックをごまかすことができます)。
トラブルシューティングには、次の方法が役立ちます。
oathtool -v --now "now -30 minutes" -w 120 --totp $SECRET
30 秒間隔のサイズの場合、30 分前から 30 分後までの 1 時間分の値が生成されることになります。この値から、トークン オフセットまたはクロック オフセットを推測できます (diff -y
出力を並べて比較すると便利です)。TOTP は「UNIX 時間」を使用するため、タイムゾーンが不正確なクロックの大きなオフセットを「隠している」場合を除き、タイムゾーンは問題になりません。
--now
堅牢な GNU 日付/時刻パーサーを使用し--epoch
、絶対タイムスタンプだけでなく相対時間指定もサポートします--now "30 min ago"
。
OP が決定したように、デフォルトのエポックとタイムステップでは、時間が正しい場合、正しくないのは秘密であるはずです。
答え2
Google Authenticator と oathtool を同期しました:
secret=`echo 1234567812345678 | base32`
oathtool -v --totp -b $secret
qrencode -t ANSI "otpauth://totp/test?secret="${secret}""