我在写一个socket程序,用了Apache的Mina,现在想加入SSL机制。搜了很多资料后,写了一些代码,但是发现一个很奇怪的问题,就是客户端随便用什么证书都能与服务端建立SSL连接。我是参考这篇文章写的SSL部分的代码,主要是生成SSLContext
http://www.vlan9.com/problems/d541174608.html首先我用keytool生成了下面这些证书
keytool -genkey -alias alice -keystore clientKeys 
keytool -genkey -alias bob -keystore clientKeys 
keytool -genkey -alias server -keystore serverKeys 
keytool -export -alias server -keystore serverKeys -file server.cer 
keytool -export -alias alice -keystore clientKeys -file alice.cer 
keytool -export -alias bob -keystore clientKeys -file bob.cer 
keytool -import -alias server -keystore clientTrust -file server.cer
keytool -import -alias alice -keystore serverTrust -file alice.cer
keytool -import -alias bob -keystore serverTrust-file bob.cer 服务端中生成SSLContext的代码是这样的        private KeyManager[] getKeyManagers() throws IOException,
GeneralSecurityException { // 获得KeyManagerFactory对象. // String alg = KeyManagerFactory.getDefaultAlgorithm(); String alg = "SunX509"; KeyManagerFactory kmFact = KeyManagerFactory.getInstance(alg); // 配置KeyManagerFactory对象使用的KeyStoree.我们通过一个文件加载 // KeyStore. FileInputStream fis = new FileInputStream("serverKeys"); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(fis, "123456".toCharArray()); fis.close(); // 使用获得的KeyStore初始化KeyManagerFactory对象 kmFact.init(ks, "123456".toCharArray()); // 获得KeyManagers对象 KeyManager[] kms = kmFact.getKeyManagers(); return kms; } private TrustManager[] getTrustManagers() throws IOException,
GeneralSecurityException { // 获得KeyManagerFactory对象. // String alg = KeyManagerFactory.getDefaultAlgorithm(); String alg = "SunX509"; TrustManagerFactory kmFact = TrustManagerFactory.getInstance(alg); // 配置KeyManagerFactory对象使用的KeyStoree.我们通过一个文件加载 // KeyStore. FileInputStream fis = new FileInputStream("serverTrust"); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(fis, "123456".toCharArray()); fis.close(); // 使用获得的KeyStore初始化KeyManagerFactory对象 kmFact.init(ks); // 获得KeyManagers对象 TrustManager[] kms = kmFact.getTrustManagers(); return kms; }
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(getKeyManagers(), getTrustManagers(), null);
/code]客户端的代码如下[code="java"]
                String key = "mySrvKeystore"; // 要使用的证书名 char keyStorePass[] = "123456789".toCharArray(); // 证书密码 char keyPassword[] = "123456789".toCharArray(); // 证书别称所使用的主要密码
                KeyStore ks; ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(key), keyStorePass); // 创建管理JKS密钥库的X.509密钥管理器
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, keyPassword); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(),
BogusTrustManagerFactory.X509_MANAGERS, null);上面的mySrvKeystore是用keytool随意生成的另一个证书,没有导入最前面生成serverKeys证书的相关信息。
BogusTrustManagerFactory.X509_MANAGERS是Mina一个例子中的代码,如下public class BogusTrustManagerFactory extends TrustManagerFactorySpi {    static final X509TrustManager X509 = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] x509Certificates,
                String s) throws CertificateException {
        }        public void checkServerTrusted(X509Certificate[] x509Certificates,
                String s) throws CertificateException {
        }        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    };    public static final TrustManager[] X509_MANAGERS = new TrustManager[] { X509 };
原本在客户端代码中我是用到了最上面生成的clientKeys和serverTrust证书的,可以建立SSL连接,通信没问题。
但是随便用keytool生成另一个证书mySrvKeystore之后,客户端也能与服务端建立SSL连接并通信这是怎么回事呢?
请问怎么解决这个问题?谢谢