我想实现一个小型的Android应用程序,该应用程序可以用作SSL Server。
在使用正确的密钥库格式遇到了许多问题之后,我解决了这个问题,然后运行到下一个。

我的密钥库文件已由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()


会以不同的组合打印long list。但是我不知道如何获取受支持的密钥。
在使用portecle将其转换为BKS格式后,我也尝试了android debug keystore,但仍然遇到相同的错误。

谁能帮忙告诉我如何生成与其中一个密码套件兼容的密钥?

版本信息:

targetSDK:15
在运行4.0.3的模拟器和运行2.3.3的真实设备上进行了测试
弹跳城堡1.46
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());
    }
}
}

最佳答案

密钥库不支持已启用的密码套件


密钥库是否真正需要支持还是不取决于密码套件。支持它们的是SSLSocket(或引擎)。它正在寻找的是密钥库中适合其支持的密码套件之一的密钥。通常,启用的密码套件基于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(并且没有默认的密钥库):这就是为什么您收到“找不到任何密钥库条目来支持启用的密码套件的原因” “:找不到合适的密钥库条目,因为它甚至找不到密钥库。

您将需要配置SSLContext,使用从密钥库构建的KeyManager对其进行初始化,然后从中获取服务器套接字工厂。

关于java - SSLException:找不到任何 keystore 条目来支持已启用的密码套件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10010126/

10-12 03:53