0

SSL サーバーとして機能する小さな Android アプリケーションを実装したいと考えています。キーストアの正しい形式に関する多くの問題の後、私はこれを解決し、次のものに遭遇しました。

キーストア ファイルが KeyStore クラスによって適切に読み込まれます。しかし、サーバー ソケット (socket.accept()) を開こうとすると、次のエラーが発生します。

javax.net.ssl.SSLException: 有効な暗号スイートをサポートするキー ストア エントリが見つかりませんでした。

次のコマンドでキーストアを生成しました。

keytool -genkey -keystore test.keystore -keyalg RSA -keypass ssltest -storepass ssltest -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov.jar

Java SE6 の無制限強度管轄ポリシーが jre6 に適用されます。

呼び出して、サポートされている暗号スイートのリストを取得しました

socket.getSupportedCipherSuites()

非常に異なる組み合わせで長いリストを出力します。しかし、サポートされているキーを取得する方法がわかりません。portecle を使用して BKS 形式に変換した後、Android デバッグ キーストアも試しましたが、それでも同じエラーが発生します。

暗号スイートの1つと互換性のあるキーを生成する方法を教えてくれる人はいますか?

バージョン情報:

targetSDK:
4.0.3 を実行するエミュレーターと 2.3.3 を実行する実際のデバイスでテストされた15
BounceCastle 1.46
portecle 1.7

私のテストアプリケーションのコード:

public class SSLTestActivity extends Activity implements Runnable {
SSLServerSocket mServerSocket;
ToggleButton tglBtn;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    this.tglBtn = (ToggleButton)findViewById(R.id.toggleButton1);

    tglBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                new Thread(SSLTestActivity.this).run();
            } else {
                try {
                    if (mServerSocket != null)
                        mServerSocket.close();
                } catch (IOException e) {
                    Log.e("SSLTestActivity", e.toString());
                }
            }
        }
    });
}

@Override
public void run() {
    try {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(getAssets().open("test.keystore"), "ssltest".toCharArray());

        ServerSocketFactory socketFactory = SSLServerSocketFactory.getDefault();
        mServerSocket = (SSLServerSocket) socketFactory.createServerSocket(8080);
        while (!mServerSocket.isClosed()) {
            Socket client = mServerSocket.accept();
            PrintWriter output = new PrintWriter(client.getOutputStream(), true);
            output.println("So long, and thanks for all the fish!");
            client.close();
        }
    } catch (Exception e) {
        Log.e("SSLTestActivity", e.toString());
    }
}
}
4

2 に答える 2

2

キーストアは、有効な暗号スイートをサポートしていません

暗号スイートをサポートするかどうかは、実際にはキーストア次第ではありません。それらをサポートするのはSSLSocket(またはエンジン) です。探しているのは、キーストア内の、サポートされている暗号スイートの 1 つに適したタイプのキーです。通常、有効な暗号スイートは RSA または DSS ベースであるため、それぞれ RSA または DSA キーを探します。

次のコードでは:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(getAssets().open("test.keystore"), "ssltest".toCharArray());

ServerSocketFactory socketFactory = SSLServerSocketFactory.getDefault();
mServerSocket = (SSLServerSocket) socketFactory.createServerSocket(8080);

あなたはあなたのkeyStore. この場合、まったくロードしない方がよいでしょう (ちなみに、読み込んだ入力ストリームは常に閉じる必要があります)。

ここでは、SSLServerSocketFactory特に構成していない (そしてデフォルトのキーストアがない) default をまだ使用しています。キー ストアさえ見つからないため、適切なキー ストア エントリを見つけることができません。

を構成し、キーストアからビルドされたSSLContextで初期化し、KeyManagerそこからサーバー ソケット ファクトリを取得する必要があります。

于 2012-04-04T11:51:29.940 に答える