在以编程方式添加证书时,自签名证书是否总是容易受到中间人攻击?

时间:2015-07-30 09:21:55

标签: java ssl jax-ws java-security

我正在创建一个需要接受自签名证书的jax-ws客户端应用程序。但是当您尝试导入自签名证书时,会出现这种常见的SSL Handshake exception problem。因此,最常见的解决方法是扩展JSSE安全提供程序并初始化SSL上下文以接受所有证书,如:

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
TrustManager[] trustCerts = new TrustManager[]{new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }

                       public void checkServerTrusted(X509Certificate[]
                       certs, String authType) throws CertificateException {
                            return;
                        }

                        public void checkClientTrusted(X509Certificate[]
                        certs, String authType) throws CertificateException {
                            return;
                        }
                    }
            }; 
SSLContext sc = SSLContext.getInstance("SSLv3");
sc.init(null, trustCerts, null);
SocketFactory factory = sc.getSocketFactory();
SSLSocket socket;
socket = (SSLSocket) factory.createSocket(mInstance.getHostName(),getSecureConnectionEndpoint().getPort());
socket.startHandshake();
setCerts(socket.getSession().getPeerCertificates());

这是我能找到问题的唯一解决方法。这里有许多类似的问题,如Import SSL certificates,他们都提出相同的解决方案。

这显然很容易让人处于中间攻击状态,而且这种解决方案似乎只是出于测试目的而合法。

所以我的问题是,当您尝试以编程方式导入证书时,是否无法使整个过程更安全?

提前谢谢!

3 个答案:

答案 0 :(得分:0)

  

这显然很容易让人处于中间攻击状态,而且这种解决方案似乎只是出于测试目的而合法。

正确。这是完全不安全的。

  

所以我的问题是,当您尝试以编程方式导入证书时,是否无法使整个过程更安全?

如果您是通过您尝试保护的频道进行的,请不要这样做。需要信任的证书需要通过其他方式提供。

NB您发布的代码不符合var mparam = (Tuple<TItem, TParam>)item2的合同。它不能返回null。

答案 1 :(得分:0)

或许,不是使用自签名证书,而是更好地创建证书颁发机构并信任它?

我使用XCA运行自己的私有CA并颁发证书 - 它非常易于使用和理解。

为了让Java信任您的CA,您需要导入根证书 - 使用keytool创建信任存储

keytool -importcert -file myca.crt -keystore mykeystore.jks

然后使用以下JVM arg

导入信任库
-Djavax.net.ssl.trustStore=/home/user/mykeystore.jks

答案 2 :(得分:0)

无论是自签名还是由CA签名,加密都可以正常工作。唯一的区别是,如果您自签名,它将显示一条警告,表明您拥有自己在网站上进行的操作,并且生成的服务器可以解密您的个人信息,并可用于恶意目的。对于自签名,您无法验证服务器是否为其所声称的人。无论是自签名还是由CA签名,数据都是加密的,对于中间攻击的人,我发现没有区别。可能是有人使用wireshark或nmap等嗅探数据包,但在两种情况下,无论是自签名还是由CA签名,都是相同的。通常对于开发和测试使用自签名证书,并使用prod CA签名证书。您不希望最终用户接受与网站相关的风险,以节省很多钱。

  If you are consuming the service in Java code you need to import the self 
 signed certificate in cacerts present in <PATH_TO_JRE>\lib\security\cacerts by
 the following command >keytool -import -alias <Alias Name> -file "PATH_TO_.crt"
 -keystore "PATH_TO_cacerts" -ext san=ip:127.0.0.1 

您还可以在san中使用域名,例如www.mydomain.com,而不是ip