概述

HTTPS相对于HTTP多了SSL(security sock layer),应用层将数据丢给TCP时,需要经过SSL层的加密处理;TCP层的数据丢给应用层时,需要经过SSL层的解密处理。因此网络中传输的都是加密后的数据,提高的通信的安全性。

HTTPS除了拥有传输加密的功能,还提供身份认证,防止对端伪造身份。这个是通过HTTPS证书实现。

  • 注下图中对HTTPS握手过程进行简化,握手过程的关键步骤就是证书校验及对称加密秘钥的协商,另外客户端证书的校验是可选的。

问题

标准证书都是第三方机构颁发的,需要付费找第三方机构申请。有些出于节省成本或者省事的目的,一般会使用工具生成自签名的证书。浏览器访问这种自签名证书的网址时就会弹出不安全的提示,如果是java代码访问这种网址时就会抛出异常。
解决这种问题有2个途径,一种是忽略证书认证,另一种就是将自签名的证书添加到受信证书库中。

SSLContext关键参数说明

SSLContext都是通过SSLContext.getInstance(String protocol)方法获取,获取后需要调用init方法初始化。init方法签名如下:
public final void init(KeyManager[] km, TrustManager[] tm,SecureRandom random)

  • KeyManager
    用于HTTPS双向认证时,客户端向服务端发送的认证信息(证书);与不同的服务端交互时,客户端可能用不同的身份(证书),所以需要KeyManager进行管理。
    如果只是单向认证,KeyManager[]可以为空
  • TrustManager
    用于客户端检测服务端发送过来的证书。

KeyStore:只是单纯的存储证书、秘钥数据,不包含任何逻辑。TrustManager,KeyManager可以使用KeyStore得到证书列表进行相应的业务处理。

忽略证书认证

有些语言比如Python是可以修改全局配置去忽略证书检查,但是Java好像没有提供这种功能,所以需要覆写证书认证的类X509TrustManager 。
忽略证书认证后,双方通信的时候仍然是加密的,只是无法对服务端的身份进行认证,有服务端伪造的风险。如果都是在内网,可以采用这种简洁的手法。

public SSLContext buildSSLContext() throws Exception {X509TrustManager x509TrustManager = new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}};SSLContext sslContext = SSLContext.getInstance("TLSv1.2");sslContext.init((KeyManager[]) null, new X509TrustManager[] {x509TrustManager}, (SecureRandom) null);return sslContext;
}

将自签名证书放到受信证书库

将证书直接导入到JDK的证书库

待续

通过编码的方式将证书放到受信证书列表中

@Override
public SSLContext buildSSLContext() throws Exception {KeyStore keyStore = buildKeyStore();TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());tmf.init(keyStore);SSLContext sslContext = SSLContext.getInstance("TLSv1.2");sslContext.init((KeyManager[]) null, tmf.getTrustManagers(), (SecureRandom) null);return sslContext;
}private KeyStore buildKeyStore() throws Exception {// 获取自签名的证书List<X509Certificate> certs = loadHttpsCerts();KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());keyStore.load(null, null);TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init((KeyStore) null);// 获得jdk证书库中的证书Arrays.stream(trustManagerFactory.getTrustManagers()).filter(manager -> manager instanceof X509TrustManager).findFirst().ifPresent(manager -> {List<X509Certificate> jdkCerts = Arrays.asList(((X509TrustManager) manager).getAcceptedIssuers());certs.addAll(jdkCerts);});certs.stream().forEach(cert -> {keyStore.setCertificateEntry(cert.getSubjectDN().getName(), cert);});return keyStore;
}private List<X509Certificate> loadHttpsCerts() throws IOException, CertificateException {List<X509Certificate> certs = new ArrayList<>(32);PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource[] resources = resolver.getResources(HTTPS_CERTS_PATH);for (Resource resource : resources) {InputStream inStream = resource.getInputStream();CertificateFactory factory = CertificateFactory.getInstance("X.509");X509Certificate cert = (X509Certificate) factory.generateCertificate(inStream);certs.add(cert);}return certs;
}

java SSLContext创建相关推荐

  1. Java中创建泛型数组

    Java中创建泛型数组 使用泛型时,我想很多人肯定尝试过如下的代码,去创建一个泛型数组 T[] array = new T[]; 当我们写出这样的代码时编译器会报Cannot create a gen ...

  2. 【JVM】Java对象创建的流程步骤

    · 本文摘要 · 罗列Java创建对象的各种方式: · 讲解Java对象创建的流程步骤: 一.Java创建对象的各种方式 · 1. 用关键字new,老少皆知的方法:StringBuffer sb = ...

  3. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)

    摘要:本节主要来讲解Android10.0 JAVA层的HIDL服务创建和JAVA层的Client验证 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  4. 如何在Java中创建一个新的List

    本文翻译自:How to make a new List in Java We create a Set as: 我们创建一个Set为: Set myset = new HashSet() How d ...

  5. akka actor java_Akka:使用非默认构造函数在Scala中定义一个actor并从Java代码创建它 - java...

    Akka Scala演员必须扩展akka.actor.Actor Akka Java actor必须扩展akka.actor.UntypedActor 因此,在使用非默认构造函数定义Scala act ...

  6. 写文件 追加_总结Java中创建并写文件的5种方式

    在Java中有很多的方法可以创建文件写文件,你是否真的认真的总结过?下面小编就帮大家总结一下Java中创建文件的五种方法. 在java中有很多的方法可以创建文件写文件,你是否真的认真的总结过?下面笔者 ...

  7. java creat uid_关于uniqueidentifier:如何在Java中创建唯一ID?

    本问题已经有最佳答案,请猛点这里访问. 我正在寻找在Java中创建唯一ID作为String的最佳方法. 任何指导表示赞赏,谢谢. 我应该提到我正在使用Java 5. 看看这个stackoverflow ...

  8. java session创建_request创建session

    如何在 Java 中创建 session ? 使用request对象获取session,然后进行操作. 1,引入包servlet-api.jar . 2,使用request获取session:Http ...

  9. java闪屏怎么制作,Java Swing创建自定义闪屏:在闪屏下画进度条(一)

    Java Swing创建自定义闪屏:在闪屏上画进度条(一) 由于本人十分热爱Java Swing,所以平时闲暇之余总是喜欢极尽所能去搜藏一些自认为比较"酷"的Swing代码来研究揣 ...

最新文章

  1. 算法系列15天速成——第二天 七大经典排序【中】
  2. Matlab-PEAKS函数曲线
  3. 2017年第八届蓝桥杯C/C++ A组国赛 —— 第四题:填字母游戏
  4. [转]RxHttp 一条链发送请求,新一代Http请求神器(一)
  5. const 常量_var,let,const 的区别?
  6. 内网服务器时间修改,内网(无网络)搭建ntp时间同步服务
  7. matlab虚拟现实之工具介绍(修改)
  8. Leetcode 413.等差数列划分
  9. .net core linux服务,.netcore在linux服务生成
  10. golang高级部分
  11. HTML实现页面注册
  12. VS2015开发工具里面没有Arial字体怎么办?VS如何添加字体
  13. if else 条件语句
  14. 计算机word表格公开课ppt,制作Word表格公开课).ppt
  15. 读书笔记-《启示录--打造用户喜爱的产品》
  16. 用了MybatisPlus后,我很久没有手写sql了
  17. project导出html格式,前端导出xslx.html
  18. 网易云音乐 音乐外链
  19. 马来西亚SIRIM认证
  20. linux命令---top

热门文章

  1. 请看我们的天才球迷的自荐信:
  2. Android仿微博、人人Feed详情页吸附导航栏
  3. 第十二章项目案例:QQ数据库管理
  4. RTX2060和GTX1070Ti 哪个好
  5. html填色游戏源码,canvas的填色画游戏代码
  6. mac连接蓝牙耳机无法连接如何处理?
  7. Python 实现ARP扫描与欺骗
  8. 苹果电脑截屏的几种办法
  9. 2018年Android的保活方案效果统计
  10. APP抓包神器drony