2012-04-16 17 views
2

AndroidでJavaを使用して確定的にRSA鍵ペアを生成しようとしています。私の要件は、私がキーペアを格納することができないようなものであり、それは実行時に、以前/将来の実行と同等に生成されなければならない。RSA暗号鍵ペアの確定的な生成

私は、乱数ジェネレータを決定論的にシードして、そのジェネレータをキーを作成するために渡しました。私のコードは

SecureRandom random=SecureRandom.getInstance("SHA1PRNG"); 
random.setSeed(1234); //something device specific will be used to set this 
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA"); 
keyGen.initialize(1024, random); 

KeyPair pair=keyGen.generateKeyPair(); 
PublicKey pub=pair.getPublic(); 
PrivateKey priv=pair.getPrivate(); 

です。実行されるキーは実行時と異なります。ただし、SecureRandomの数値は実行ごとに同じで、デバイス間でも同じです。

私には何が欠けていますか?どのようにこれらのキーを繰り返し生成できますか?

ありがとうございました

+0

なぜこれをやりたいですか? RSA鍵ペアを格納したくない場合は、RSAペアを生成するために使用されたランダムシードも格納したくないでしょうか?このコードがあなたが望むようなことをしていないのは奇妙ですが、私にはそれを考えずにこれをやっているようです。 –

答えて

8

何をしようとしていますか?このコードが動作しても、このコードはAndroid上のSHA1PRNG実装の変種に依存するため、いつでも破損する可能性があります。一般にsetSeed()はエントロピーを追加しますので、同じシードのSecureRandomをシードしても同じ数字が得られるとは限りません。デスクトップJavaでこのコードを試してみると、おそらく失敗するでしょう。これまでのところ、ほとんどの(すべての)現在のAndroidバージョンで動作しますが、これは保証されていません。

予測可能なキーが必要な場合は、各デバイスに事前生成キーをプロビジョニングする必要があります。それらを安全に保管する必要がある場合は、ICSのKeyChain API、またはICS前のデバイスのパスフレーズ保護キーストアを使用してください。実際のキーを格納していなくても、キーがどのように生成されるのか(種)を知っていれば、同じキーを生成することができます。デバイス固有の場合は、見つけにくい可能性があります。

これがうまくいかない理由としては、RSA鍵生成器は基本的にループ内でランダムBigIntegersを生成し、素数をテストします。プライムテストは確率的なので、実行ごとに異なる素数を選ぶかもしれません。 SpongyCastleを取得し、エミュレータでこれを実行し、正確に何が起こっているかを確認するために、RSAKeyPairGenerator.javaにブレークポイントを設定するとよいでしょう。

+0

キージェネレーターの動作とSpongyCastleの実装方法の詳細な説明をありがとう。これはすべて、アプリ内購入によるコンテンツの著作権侵害を最小限に抑えるための(誤った)試みの一部です。私の希望は、サーバー上のコンテンツを暗号化し、鍵交換なしにクライアントに配信し、その場でコンテンツを復号化できることでした。私はサーバー上で鍵ペアを生成し、秘密鍵をクライアントに送信し、鍵ストアを使用する必要があります。 – Aaron

+0

私は(種類)を参照してください。あなたは一種のDRMを実装しようとしています。 RSAはこれには最適ではないかもしれません。鍵をクライアントに送信する場合は、当然これが確実に行われることを確認する必要があります。これは簡単ではないかもしれません。アイデアでは、デバイス固有のビット(IME​​Iなど)をIAB developerPayloadに配置し、サーバー上の署名を検証するときに取得します。これを使用して、特定のデバイスにバインドされた対称(AES)キーを生成し、コンテンツを暗号化してデバイスに送信します。次に、デバイスは同じ対称鍵を生成し、コンテンツを復号化する。 –

+0

実際のデバイス識別情報を収集しないように、IMEIなどをハッシュすることもできます。 –

関連する問題