web-dev-qa-db-ja.com

Android RSAキーペアの生成-標準のJava / Bouncy Castle / Spongy Castle / JSch / Otherを使用する必要がありますか?

私は自分の考えている方法を実装するために、約1週間以上探し回っています。私はこれらのさまざまな方法のすべてについて多くの記事に出会いました(そして読んだ)が、私はまだ混乱しているので、誰かがこれらのトピックに関する知識を広め、私が求める方法をより簡単に作成できるようになりたいと思っていました。 Androidで実装します。

私の「求められる」方法:

  1. RSA公開鍵と秘密鍵を生成する必要があります
  2. パブリックにはPKCS#1パディングが必要
  3. RSA 2048である必要があります
  4. バイト配列で公開鍵を返す

どうやらあなたはそれについて4つの方法をとることができます:

  1. 標準Java
  2. 弾む城
  3. 海綿城(Androidフレンドリー?)
  4. JSch

私はセキュリティに非常に慣れていないので、Java全体として、誰かがこれについてすべて明確に明確に説明できるかどうか疑問に思っていました。

以下は、私が求めているメソッド(上記)を4つの異なるプログラミングメソッドに実装しようとした方法です。何かわからない場合は、それぞれのドキュメントを理解できないためです。お気軽に訂正ください。

1.標準Java(PKCS#1かどうか不明):

public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(2048);
    KeyPair keyPair = kpg.genKeyPair();
    byte[] pri = keyPair.getPrivate().getEncoded();
    byte[] pub = keyPair.getPublic().getEncoded();
    return pub;
}

2.弾む城(まだ機能していない= /アイデア?):

public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
    RSAKeyPairGenerator r = new RSAKeyPairGenerator();
    r.init(new KeyGenerationParameters(new SecureRandom(),4096));
    AsymmetricCipherKeyPair keys = r.generateKeyPair();
    CipherParameters pri = keys.getPrivate();
    CipherParameters pub = keys.getPublic();
    byte[] pubbyte = pub.toString().getBytes();
    return pubbyte; //NOT WORKING
}

3. SpongyCastle(開始していません/ Bouncy Castleと同じですか?):

4. JSch(非常に機能不全/進行中の作業)

public byte[] returnPublicKeyInBytes(JSch jSch) {
    try { 
        KeyPair keyPair = KeyPair.genKeyPair(jSch, KeyPair.RSA);
        ByteArrayOutputStream bs = new ByteArrayOutputStream(); 
        keyPair.writePrivateKey(bs); 
        jSch.addIdentity("Generated", bs.toByteArray(), keyPair.getPublicKeyBlob(), null);
        return keyPair.getPublicKeyBlob(); 
    } catch (JSchException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    }
    return null;
}

Android(私や他の多くの人がそうであるように)で)RSAキーの生成に問題がある人のために、これをもっとリソースにしたいと思います。


Bouncy Castleにはvery little APIに関する情報があるため、初心者(私のような)が理解しにくい極端に難しいと感じています。私の調査によると、人々は組み込みのセキュリティプロバイダーの代わりにJavaでBouncy Castleを使用しています。これはBouncy Castleの方がはるかに堅牢であるためですBouncy Castle in Android望ましくありませんこれは「Bouncy Castleの機能が損なわれたバージョンで出荷される」ため、エラーが発生する可能性があります。SpongyCastleは、Bouncyの単なるrepackageです。城。

このため、最後の質問をします。Androidではどの方法を使用する必要がありますか?

更新

後で誰かがこれに答えられることを願っています。問題を解決するために私がしたことは、NDKを使用することでした。

34
EGHDK

複雑ですが、できる限り説明します。 Javaから始めようと思います。私の議論はJava 6を対象としています。Java 7.で何が変更されたかはわかりません。

Javaの組み込み暗号化は、Java Cryptography Extension(JCE)を通じて利用できます。この拡張機能には、アプリケーションAPIとサービスプロバイダーAPIの2つの部分があります。アプリケーションAPIは、ユーザーが操作する部分ですさまざまな暗号化クラスのgetInstance()ファクトリメソッドを使用します。サービスプロバイダーの側面は、平均的なプログラマーにとってより混乱します。暗号化の実装方法は気にせず、機能するものを望んでいるだけです。しかし、内部には実際の作業を行う暗号プロバイダークラスがあります。getInstance()の引数を見ると、必要に応じてプロバイダーを指定できることがわかります。 ?おそらく、RSAの最適化された商用実装に$$$を支払ったので、それを使用したいと思います。おそらく、1つのプロバイダーが、アプリに必要なFIPS証明書またはその他の証明書を持っています) 。次に、そのプロバイダーを指定します。Sun/ Oracle ships their Java environment with some prov iders これは、Java環境用に設定されたデフォルトのプロバイダーを一緒に構成します。それらは重なり合っており、歴史的なアーティファクトによって多少混乱するため、あまり注意深く見ないでください。基本的に、Oracleを使用する場合Java KeyPairGeneratorからKeyPairGenerator.getInstance("RSA");のような暗号を要求すると、これらのいずれかから適切なクラスインスタンスが取得されますプロバイダー。

次に、バウンスキャッスルを見てみましょう。 bouncycastleライブラリは2つの部分で構成されています。 1つは、上記の#2で実験したAPIを持つ独自の暗号ライブラリです。 2番目の部分は、このライブラリをJCEの暗号化プロバイダーとして使用できるようにするための多くのグルーコードです。これは、プログラマーとしてbouncycastle暗号ライブラリーの使用方法を選択できることを意味します。上記の#2のように、直接APIを使用できます。または、JCE APIを使用できますが、KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");などのようにして、バウンスキャッスルの実装を明示的に指定します。

独自のBouncycastle APIを直接使用する(「軽量API」と呼ぶ)場合は、JCEプロバイダーとして機能させるために使用するすべてのグルーコードを使用する必要はありません。このため、バウンスキャッスルは軽量APIクラスのみのダウンロードを提供します。

そして最後に、Androidの実装を見てみましょう。 GoogleはOracleのJavaソースコードをライセンスしていなかったため、OracleのJCEプロバイダーはありませんでした。独自のプロバイダーを提供する必要がありました。bouncycastleには必要なすべてのコードがあり、オープンだったためソースと自由にライセンスされたGoogle/Androidは、デフォルトのJCEプロバイダーのベースとしてbouncycastleを使用することを選択しました。しかし、Androidは、Androidプログラマー。JCEを通じてのみこれらのクラスを使用することを期待しています。バウンスキャッスルコードを変更してAndroid向けに調整しました。彼らは、軽量APIの直接Androidは、内部にあるという事実の副作用です。すべてがあるわけではありません。この状況は、「Androidのバウンスキャッスルが機能しなくなった」として発生します。

Android一部の開発者が Spongycastleライブラリ と呼ばれるものを作成した一部の開発者がbouncycastleライブラリのフル機能バージョンを実際に提供するにはAndroidで動作します。主な変更は、名前空間の競合を防ぐために、パッケージ名をorg.bouncycastle.*からorg.spongycastle.*に変更することでした。

それであなたは何を使うべきですか?それは、何をしたいか、どのような移植性のニーズがあるか、スタイルの好みは何か、暗号スキルレベルは何であるかによって異なります。一般に、これらのライブラリを使用しているときは、かなり低いレベルで暗号を使用しています。方法(キー転送にRSAを使用し、メッセージの暗号化にAESを使用し、メッセージの整合性にHMAC-SHA256を使用するなど)と実行する方法(メールで暗号化されたメッセージを受信者に送信したい)に集中しているのようなメカニズム)。もちろん、できれば、問題を直接解決する高レベルのライブラリを使用する必要があります。これらのライブラリは、PKCS#1とは何か、およびそれをより大きくより完全なプロトコルの一部として使用する方法をすでに理解しています。

今日は弾む城で今日誰かを助けていた。彼のコードは機能するので、チェックしてください

弾力がある城を使用して生成するRSAキーペア。コードをJavaプログラム から実行可能にする

1
Mayank