この記事は、インテル® デベロッパー・ゾーンに掲載されている「Sample Code: Random Number Application」(http://software.intel.com/en-us/android/articles/sample-code-random-number-application) の日本語参考訳です。
サンプルコードのダウンロード: https://software.intel.com/sites/default/files/managed/16/df/RandomNumber.zip
アプリケーション提供元:
インテル コーポレーション SSG
はじめに
乱数ジェネレーター (RNG) とは、値が予測できない、ある範囲内の一連の数を生成するユーティリティーまたはデバイスです。RNG は、情報セキュリティー・アプリケーションに不可欠なコンポーネントです。事実、暗号プロトコルには相当な強健さが備わっていますが、根本的な鍵生成手法が弱い場合は、広範な攻撃に苦しめられることになります。ハードウェア支援による RNG を使用すると、この脆弱性を解消できるため、暗号の強度を大幅に高めることができます。
この記事では、乱数 API の概要を示し、Android* 上でさまざまな API を用いて乱数を生成する方法を説明します。
すべてのコードをコンパイルして試してみることをお勧めします。
コードと説明
Android* で乱数を生成する方法は 4 つあります。
- java.util.random
- java.security.SecureRandom
- /dev/urandom
- OpenSSL* API
ただし、RNG を使ってデータを保護する暗号鍵を生成する場合、通常の Random クラスは簡単に解読できるため、使用すべきではありません。ほかの 3 つのアプローチは、強固な鍵を提供します。
java.util.random
Java* 乱数 API の使い方は簡単です。Random.nextInt() 呼び出しは、4 バイトの乱数 (2^32 個の値が可能) を返します。この API は、厳密な乱数が必要ない場合に使用します。
for (int i = 0; i < lastVal; i += 2) { dataRandomPoints[i] = (rand.nextInt() % widget_width); dataRandomPoints[i+1] = (rand.nextInt() % widget_height); }
java.security.SecureRandom
SecureRandom resembles java.util.Random の SecureRandom.nextInt() 呼び出しは、4 バイトの乱数を返します。SecureRandom の暗号は非常に強固です。ただし、乱数を生成する前に、/dev/urandom からのバイトを SecureRandom のシードとして使用することに関する推奨事項 (英語) を一読すべきです。以下のサンプルでは、/dev/urandom をシードとして使用していません。
SecureRandom srand = new SecureRandom(); shouldDraw = (srand.nextInt() % randomMod );
/dev/urandom
Linux* オペレーティング・システム (Android* を含む) では、カーネルによって作成される特別なファイルを利用して、アプリケーションに乱数を提供することができます。4 つの実装のうち最も低速なこのアプローチは、RNG にオペレーティング・システムに関する要素 (例えば、デバイスドライバーなど) を組み込むことで、強固に暗号化された高エントロピーな値を生成します。/dev/urandom ファイルから読み取ることで、カーネルレベルから直接乱数を取得できます。可能であれば、/dev/urandom はハードウェア支援による RNG を利用します。
unsigned int cKeyBuffer[keysize]; memset(cKeyBuffer, 0, sizeof(unsigned int) * keysize); FILE *fin; strcpy(filein, "/dev/urandom"); fin = fopen(filein, "rb"); if (fin != NULL) { fread(cKeyBuffer, sizeof(int), keysize, fin); fclose (fin); }
OpenSSL API
ネイティブ C コードでは、OpenSSL API により乱数を生成することもできます。OpenSSL は、/dev/urandom からのバイトをシードとして利用できるため、安全性の高い暗号化された乱数を生成できます。可能であれば、OpenSSL はハードウェア支援による RNG を利用します。
int seedbytes = 1024; unsigned int cKeyBuffer[keysize]; memset(cKeyBuffer, 0, sizeof(unsigned int) * keysize); if (!opensslIsSeeded) { if (!RAND_load_file("/dev/urandom", seedbytes)) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to seed OpenSSL RNG"); return jKeyBuffer; } opensslIsSeeded = 1; } if (!RAND_bytes((unsigned char *)cKeyBuffer, keysize * sizeof(int))) { __android_log_print(ANDROID_LOG_ERROR, TAG, "Faled to create OpenSSSL random integers: %ul", ERR_get_error); }
まとめ
この記事で説明したサンプルのようなコードを実装することにより、4 つの異なるアプローチを使って乱数を生成する方法を素早く理解できます。
著者紹介
Christopher Bird
インテル コーポレーションのソフトウェア & ソリューション・グループ (SSG) デベロッパー・リレーション部門 インテル® Atom™ プロセッサー・ハイ・タッチ・ソフトウェア・イネーブリング・チームのメンバー。
著作権と商標について
本資料に掲載されている情報は、インテル製品の概要説明を目的としたものです。本資料は、明示されているか否かにかかわらず、また禁反言によるとよらずにかかわらず、いかなる知的財産権のライセンスを許諾するものではありません。製品に付属の売買契約書『Intel's Terms and Conditions of Sale』に規定されている場合を除き、インテルはいかなる責任を負うものではなく、またインテル製品の販売や使用に関する明示または黙示の保証 (特定目的への適合性、商品適格性、あらゆる特許権、著作権、その他知的財産権の非侵害性への保証を含む) に関してもいかなる責任も負いません。
インテルによる書面での合意がない限り、インテル製品は、その欠陥や故障によって人身事故が発生するようなアプリケーションでの使用を想定した設計は行われていません。
インテル製品は、予告なく仕様や説明が変更される場合があります。機能または命令の一覧で「留保」または「未定義」と記されているものがありますが、その「機能が存在しない」あるいは「性質が留保付である」という状態を設計の前提にしないでください。これらの項目は、インテルが将来のために留保しているものです。インテルが将来これらの項目を定義したことにより、衝突が生じたり互換性が失われたりしても、インテルは一切責任を負いません。この情報は予告なく変更されることがあります。この情報だけに基づいて設計を最終的なものとしないでください。
本資料で説明されている製品には、エラッタと呼ばれる設計上の不具合が含まれている可能性があり、公表されている仕様とは異なる動作をする場合があります。現在確認済みのエラッタについては、インテルまでお問い合わせください。
最新の仕様をご希望の場合や製品をご注文の場合は、お近くのインテルの営業所または販売代理店にお問い合わせください。
本資料で紹介されている資料番号付きのドキュメントや、インテルのその他の資料を入手するには、1-800-548-4725 (アメリカ合衆国) までご連絡いただくか、インテルの Web サイト (英語) を参照してください。
性能に関するテストに使用されるソフトウェアとワークロードは、性能がインテル® マイクロプロセッサー用に最適化されていることがあります。SYSmark* や MobileMark* などの性能テストは、特定のコンピューター・システム、コンポーネント、ソフトウェア、操作、機能に基づいて行ったものです。結果はこれらの要因によって異なります。製品の購入を検討される場合は、他の製品と組み合わせた場合の本製品の性能など、ほかの情報や性能テストも参考にして、パフォーマンスを総合的に評価することをお勧めします。
本資料に含まれるソフトウェア・ソース・コードはソフトウェア・ライセンス契約に基づいて提供されるものであり、その使用および複製はライセンス契約で定められた条件下でのみ許可されます。
Intel、インテル、Intel ロゴ、Intel Atom は、アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
© 2014 Intel Corporation. 無断での引用、転載を禁じます。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。