0

我想实现一个小的 android 应用程序,它作为 SSL 服务器工作。在密钥库的正确格式出现很多问题之后,我解决了这个问题并进入了下一个问题。

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 调试密钥库,但仍然出现相同的错误。

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

版本信息:

targetSDK:15
在运行 4.0.3 的模拟器和运行 2.3.3 的真实设备上测试
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(或引擎)。它在密钥库中寻找适合其支持的密码套件之一的类型的密钥。通常,启用的密码套件基于 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然后从中获取服务器套接字工厂。

于 2012-04-04T11:51:29.940 回答
0

这对你来说可能为时已晚,但对其他人来说。

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

成功创建了密钥对,理论上应该可以工作。

我不确定的是密钥对的内容。如果您将所有内容都保留为默认值(即一直输入 enter),则 CN 的值将是“未知”。我进行了几次迭代测试并确认了它。CN=Unknown 将成功生成密钥对(可以使用 Keytool -list 确认)但在 SSL 协商期间将失败。不知何故,它将无法找到建立安全连接所需的密钥。(以下将失败,上述异常)

File: C:\Users\James\Downloads\test.keystore
    Type: BKS-V1
    Provider: BC
    Keys
        None
    Key Pairs
        mykey
            Last Modified: 07/Aug/2015 16:07:13 ICT
            Private Key
                Locked - unlock to get properties
            Certificates
                Unknown
                    Version: 3
                    Subject: CN=Unknown,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown
                    Issuer: CN=Unknown,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown
                    Serial Number: 5BA77D0F
                    Valid From: 07/Aug/2015 16:07:13 ICT
                    Valid Until: 05/Nov/2015 16:07:13 ICT
                    Public Key
                        Algorithm: RSA
                        Key Size: 2048 bits
                        Format: X.509
                        Encoded: 0x30820122300D06092A864886F70D01010105000382010F003082010A02820101009344283AD35606471D23D2F2B4DA61614C9A973932DF798DF66FE034C818BD6B0285BE860894FBD750180E2D668123442652D04BDFA6190CC28DBB2AA5EB657A428880428226D45F5B942AAB71FF05890FC4CD9A9F932F70E84A5CC118215E7FFE4C93FEFE46E8BD4B141D1742C790BACFF7B503230E263419A23BA3E8B4E7E0F4AECDF5082363AA86693502FFBAA3545F87AE7E462139CF666B35BF348CB5E61F2A62BEBA019F3C51021890A6D58093E91E6B807257DDF138BBB1044B8EB44A8F1E835A04B5EA3C53A7F024C805F28C1A28DFD12A2AC9A1335FD220AD247D951385756964DA1EDD804A13B42B6006554525954EEEBBCFD35FA0D81C93E0DEE50203010001
                        Public Exponent: 0x10001
                        Modulus: 0x9344283AD35606471D23D2F2B4DA61614C9A973932DF798DF66FE034C818BD6B0285BE860894FBD750180E2D668123442652D04BDFA6190CC28DBB2AA5EB657A428880428226D45F5B942AAB71FF05890FC4CD9A9F932F70E84A5CC118215E7FFE4C93FEFE46E8BD4B141D1742C790BACFF7B503230E263419A23BA3E8B4E7E0F4AECDF5082363AA86693502FFBAA3545F87AE7E462139CF666B35BF348CB5E61F2A62BEBA019F3C51021890A6D58093E91E6B807257DDF138BBB1044B8EB44A8F1E835A04B5EA3C53A7F024C805F28C1A28DFD12A2AC9A1335FD220AD247D951385756964DA1EDD804A13B42B6006554525954EEEBBCFD35FA0D81C93E0DEE5
                    Signature Algorithm: SHA256WITHRSA
                    MD5 Fingerprint: 47:F8:40:B9:05:71:CF:30:36:8D:B4:28:7D:FE:B7:6F
                    SHA-1 Fingerprint: 11:6F:A3:28:7F:87:97:E7:14:CE:63:A1:9D:09:85:CF:E4:7E:FE:E8
    Trusted Certificates
        None

顺便说一句:对于 Windows 开发人员,您可能希望将 Key Explorer 与 Keytool 进行比较。它具有比 Keytool 更多的功能。

于 2015-08-07T11:10:59.977 回答