JAVA原生Https Server安全设置

来源:互联网 发布:航模电调编程 编辑:程序博客网 时间:2024/06/16 21:15

工作中遇到的问题,在网上搜寻了好久终于解决了,资料很少,所以记录下来以供其他人查阅。
因为项目需要提供https请求服务,然而部门内又没有web方向的开发人员,领导又懒得去找其他部门帮忙,所以无奈把这个任务交给了我这样懂一点点java的人来做。
我大学虽然学的是java、jsp,但是说实话几年过去了,这些个知识早就还给老师了,哪里还记得怎么用,所以临时抱佛脚,发现以前一个项目里面用java原生的https server开发的东西,所以拿来借鉴一下,结果漏洞扫描扫描到了多个漏洞,多是关于SSL3.0的问题,网上大部分是tomcat的解决方案,奈何我大java还没有办法了么,最终还是解决了。
我使用com.sun.net.httpserver.HttpsServer来实现https server的服务,网上例子有很多,我就不再复述了。
在修改前,使用sslscan工具扫描结果是这样的:
这里写图片描述
这里面存在多个漏洞:

  1. SSL/TLS服务器瞬时Diffie-Hellman公共密钥过弱
  2. 支持SSLInsecureRenegotiation
  3. 支持SSLv3

解决方法(java版本1.7.0_67):

  1. SSL/TLS服务器瞬时Diffie-Hellman公共密钥过弱
    这个问题主要是由于java使用的加密套件不安全,以及密钥库位数太低导致的,容易被破解,所以从这两个方向来解决这个问题:
    • 解决密钥库位数太低:使用java工具重新生成秘钥库,生成时选择RSA加密,且秘钥长度设置2048位;
    • 解决加密套件不安全的问题:限制https服务支持的加密套件,选用非DHE的,这里有一些推荐
      public static final String[] CIPHER_ARRAY = {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA256",
      "TLS_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"};
  2. 支持SSLInsecureRenegotiation
    这个问题使用系统参数修正即可,这个方法是网上找到的,但是没有扫描工具来验证,仅供参考
    System.setProperty("sun.security.ssl.allowUnsafeRenegotiation","false");
    System.setProperty("sun.security.ssl.allowLegacyHelloMessages","false");
  3. 支持SSLv3
    这个问题跟密码套件一样,限制服务端支持的协议即可,参考:
    public static final String[] PROTOCOL_ARRAY = { "TLSv1", "TLSv1.1", "TLSv1.2"};

下面重点来了,如何设置密码套件和支持的协议呢,目前唯一可以使用的方法:

final HttpsConfigurator configurator = new HttpsConfigurator(sslContext) {            @Override            public void configure(HttpsParameters params) {                final SSLContext context = this.getSSLContext();                SSLParameters cntp = context.getDefaultSSLParameters();//获取当前配置参数                cntp.setCipherSuites(CIPHER_ARRAY);//修改配置限制支持的加密套件                cntp.setProtocols(PROTOCOL_ARRAY);//修改配置限制支持的协议                cntp.setNeedClientAuth(true);                cntp.setWantClientAuth(true);                params.setSSLParameters(cntp);//修改配置            }        };        https.setHttpsConfigurator(configurator);        https.start();

这个方法是每次请求到达服务器后回调的一个方法,只有在这个里面修改,才能生效,之前有帖子说在外面用getEngine()方法设置,我试了根本不起作用,外面只能获取,不能设置,只有在这个回调中才能修改。
修改后的扫描结果:
这里写图片描述

原创粉丝点击