スマートフォンを使用したワンタイムパスワード生成

プロローグ:この記事は先週作成され、日曜日の夜にサンドボックスの記事として送信されました。 今日、招待状を受け取りましたが、 モバイルデバイスを使用した2要素認証の問題に関する同様のテーマの記事を見つけました。 彼は元々考えられていたように記事を公開することに決め、ソースへのリンクのみを追加しました。



セキュリティ、パスワード、パスワードクラッキングなどに特化したHabrahabrに関する最近の出版物の後 ユーザーのスマートフォン上の特別なアプリケーションによって生成されるワンタイムパスワードを使用した認証のアイデアを思い付きました。 この考え方は、SecureIDデバイスで使用されている考え方と非常によく似ています(最近Habrahabrでも取り上げられました)。 現代のスマートフォンはますます多くの人が利用でき、その機能はそのようなスキームを実装するのに十分です。 この記事では、スマートフォン+ Webサイトバンドルの相互作用、いくつかの実装機能のアイデアを説明し、動作するプロトタイプを示します。







アイデアは簡単です-サイトに登録するとき、ユーザーはオプションで、スマートフォンにインストールされた認証用の特別なアプリケーションを使用してワンタイムパスワードを生成する機会を与えられます。 これを行うには、サーバー側で、ユーザーごとに一意の秘密キーが生成され、スマートフォンに転送する必要があります。 さらに、このキーに基づいて、スマートフォン側のアプリケーションはワンタイムパスワードを生成します。 各パスワードの有効期間は制限されています。 なぜなら 最新のスマートフォンにはすべてカメラが搭載されているため、秘密鍵を転送する最も簡単な方法は、スマートフォンのカメラを使用して秘密鍵を含むQRコードを読み取って認識することです。 もちろん、手動でキーを入力し、SMSで送信し、サーバーが生成したリンクを使用してキーファイルをダウンロードできますが、このようなソリューションは必ずしも便利ではありません。 この方法は、サイトでの承認の主な方法であると主張していませんが、承認のオプションの手段として使用できます。



サイトに登録する際のユーザーアクションのシーケンスは次のとおりです。





QRコードが広く普及しているため、QRコードを使用するだけで非常に大量のデータ(数百および数千文字)を転送できますが、データをエンコードする他の方法の使用を妨げるものはありません。

HOTPアルゴリズムは、ワンタイムパスワードを生成するための基礎として採用されました。 このアルゴリズムはオープンスタンダードであり、自由に利用できます。 彼に対応するRFC 4226もあります。



このアイデアを実装およびテストするために、多数のGoogle App Engine + Androidスマートフォンが選択されました。 このサイトのデモバージョンはhttp://grey-box.appspot.com/にあります。Androidベースのスマートフォン用の小さなデモアプリケーションへのリンクもあります。AndroidOSバージョン1.6以降がサポートされています。 どちらのアプリケーションも非常に単純なので、それらについて詳しく説明することはせず、最も興味深い点にのみ焦点を当てます。



両方のアプリケーションの基礎は、ワンタイムパスワードの計算です。 ユーザーがサイトにログインするたびに、特別なアプリケーションを使用してスマートフォンでワンタイムパスワードを生成します。 パスワードには期限があり、有効期間は限られています。 ユーザーが作成されたパスワードを入力すると、サーバーは同じアクションを実行します-サーバー側でパスワードを生成します。 パスワードが一致すれば、認証は成功します。 同じパスワードを生成するには、サーバーとスマートフォンが同じ初期データに基づいてパスワードを作成する必要があります。 この初期データは、ユーザーの秘密鍵と現在の時刻です。 サーバーが秘密キーを生成するとき、キーが生成された時点で(UNIXタイムスタンプの形式で)保存されます。 秘密鍵と鍵生成時間はQRコードにエンコードされ、スマートフォンに送信されます。 スマートフォンのアプリケーションは、秘密鍵と鍵生成時間を読み取り、サーバー側とスマートフォン側の時間の差を計算します。 将来、この差は時刻を同期するために使用されます。



サーバー側では、3つの主要なアクションを実行する必要があります。



以下は、Pythonコードの関連部分です。

#   . import time import hmac from hashlib import sha1 ... OTP_TTL = 300 #    ,   #   username = request.get(“username”) timestamp = int(time.time()) / OTP_TTL #    secret_key = hmac.new(str(timestamp) + username, digestmod=sha1).hexdigest().upper() #       ..
      
      







QRコードを含む画像を生成するための最も簡単なオプションは、任意のサービスを使用してさまざまなバーコードを生成することです。 このようなサービスは数多くあります。このシステムでは、Google Corporationが提供するサービスであるGoogle Charts Toolsが使用されました。 このサービスを使用すると、さまざまなグラフ、チャート、さまざまなバーコードを生成できます。 同様の方法は、実装を簡単にするためだけに使用されました。実際のシステムでは、サーバー側でバーコードを生成することをお勧めします。



 QR_TPL = "https://chart.googleapis.com/chart?chs=100x100&cht=qr&chl=%s&choe=UTF-8" qr_url = QR_TPL % ('%s:%s' % (secret_key, timestamp)) #      HTML   . ...
      
      







ワンタイムパスワード生成。



 import time import hmac from hashlib import sha1 … OTP_TTL = 300 #    ,   TRUNCATE_MASK = 0x7FFFFFFF #       MOD = 1000000 #         #   username = request.get("username") password = request.get("password") #       st = storage.gql("where user = :1", username).get() secret_key =st.secret_key #  timestamp timestamp = int(time.time()) / OTP_TTL #    ... one_time_password = str((int(hmac.new(secret_key, str(timestamp), sha1).hexdigest(), 16) & TRUNCATE_MASK) % MOD) # ...         if password == one_time_password: #   else: # 
      
      







スマートフォンの側面では、2つの主要なアクションが実行されます。



バーコードを読み取り、認識するためのライブラリがいくつかあります。おそらく最もアクティブに使用され、普及しているのは、 Zxingオープンライブラリです。 このライブラリは、Google AndroidやApple iOSを含む多くのプラットフォームをサポートしています。 このライブラリに基づいて、オープンアプリケーションのバーコードスキャナーも実装されます。このアプリケーションも非常に一般的で、多くの最新のAndroidスマートフォンにプリインストールされています。 もともとはこのライブラリをアプリケーションに統合することを目的としていましたが、インターネットやドキュメントを長時間検索した結果、これが最速かつ最も簡単な方法ではないことがわかりました。 Androidプラットフォームが提供するインテントコールメカニズムを使用することが決定されました。 このアプローチでは、必要に応じてバーコードスキャナーを追加でインストールする必要がありますが、必要な機能をアプリケーションに統合するのがはるかに簡単です。 これはこのアプローチのマイナス点ですが、プラスもあります-現在および将来のすべての可能なスマートフォンモデルに同行してサポートする必要はありません-これはZxing開発チームのタスクです 。 他のバーコード認識アプリケーションのサポートを実装することもでき、1つのバーコードスキャナーに限定されません。



以下は、 バーコードスキャナーアプリケーションの応答を呼び出して処理するために使用される小さなJavaコードです。

 ... //  Barcode Scanner Intent,      Intent intent = new Intent("com.google.zxing.client.android.SCAN"); intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); startActivityForResult(intent, 0); ... //           Barcode Scanner public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == 0) { if (resultCode == RESULT_OK) { //      String contents = intent.getStringExtra("SCAN_RESULT"); // …      … } } } ...
      
      







ワンタイムパスワード生成。



 //   import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; ... // ,       long OTP_TTL = 300; long TRUNCATE_MASK = 0x7FFFFFFF; long MOD = 1000000; ... //     String secret_key = key_storage.getString("secret_key", ""); //     long time_delta = key_storage.getLong("time_delta", 0); long local_time = (System.currentTimeMillis()/1000) / TIME_MASK; long server_time = local_time + time_delta; try { SecretKeySpec keySpec = new SecretKeySpec(secret_key.getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(keySpec); byte[] result = mac.doFinal(Long.toString(server_time).getBytes()); password = Long.toString((new BigInteger(1, result).intValue() & TRUNCATE_MASK) % MOD); } catch (NoSuchAlgorithmException e) { ... } catch (InvalidKeyException e) { ... } //     ...
      
      







スマートフォン用のシンプルなサイトプロトタイプおよびデモアプリケーションは、 http://grey-box.appspot.com/で入手できます 。 AndroidアプリケーションはAuth IDと呼ばれ、動作するために特別な許可やアクセス権は必要ありません。 唯一の要件は、QRコードのスキャンに使用されるバーコードスキャナーアプリケーションの可用性です。 現時点では、 Auth IDアプリケーションの機能は最小限であり、アプリケーションは1人のユーザーとデモサイトのみのキーを保存できます。 別のユーザーの下で登録すると、秘密鍵は既存のものの上に書き換えられます。 将来的には、この認可スキームが配布されていれば、さまざまなサイトおよびユーザーのキーの保存を追加できます。 コメントや提案があれば嬉しいです。



参照:

http://ru.wikipedia.org/wiki/QR-%D0%BA%D0%BE%D0%B4-QRコードとは

http://en.wikipedia.org/wiki/HOTP-HOTPアルゴリズムの説明

http://tools.ietf.org/html/rfc4226-HOTPアルゴリズムのRFC 4226

https://chart.googleapis.com-Google Chart Tools

http://code.google.com/p/zxing/-さまざまなバーコードをスキャンおよび認識するためのZxingライブラリ。

http://grey-box.appspot.com/-アイデアを説明するデモサイトとアプリケーション。



PSソースは、テストの登録とログイン後に利用できます。 コードはテストであり、アイデアの機能を検証するためだけに作成されたもので、実際の使用にはお勧めできません。



All Articles