我想实现一个小型的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/