1、HTTPS介绍

由于HTTP是明文传输,会造成安全隐患,所以在一些特定场景中,必须使用HTTPS协议,简单来说HTTPS=HTTP+SSL/TLS。服务端和客户端的信息传输都是通过TLS进行加密。这样就能在一定程度上避免敏感信息被截取。

在通信过程中,请求方称为客户端,响应方称为服务端。HTTPS请求流程如图:

1、客户端向服务端发送加密版本、加密算法种类、随机数信息等。

2、服务端返回客户端发送的信息并带上服务端证书(公钥证书)。

3、客户端效验服务端证书的合法性。

4、验证不通过终止通信,验证通过继续通信,客户端将自己所支持的所有加密算法全部发送给服务端供服务端进行选择。

5、服务端在客户端发送的加密算法中选择加密程度最高的机密方式。

6、服务端将选择的加密算法通过明文返回给客户端。

7、客户端收到服务端返回的加密方式后,使用该加密方式生成随机码(用作后续通信过程中加密的秘钥),使用服务端返回的公钥加密后发送至服务端。

8、服务端收到信息后,使用自己的私钥进行解密,获取加密秘钥。

在之后的通信中,客户端和服务端都将采用该秘钥进行加密。

2、自签证书的生成

生成证书和转换证书格式需要密码,秘密建议全部设置一致的。

2.1 生成根证书

# 生成root私钥

openssl genrsa -out root.key 1024

# 根据私钥创建根证书请求文件,需要输入一些证书的元信息:邮箱、域名、密码等

openssl req -new -out root.csr -key root.key

# 结合私钥和请求文件,创建根证书,有效期10年

openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650

2.2 生成服务端证书

# 创建服务端私钥

openssl genrsa -out server.key 1024

# 根据私钥生成请求文件需要证书元信息:邮箱、域名、密码等

openssl req -new -out server.csr -key server.key

# 结合私钥和请求文件创建服务端证书,有效期10年

openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650

单向认证不需要生成客户端证书,所以做单向认证的证书到此就完成了。但是为了之后的测试方便(java中作为服务端使用.p12/.jks类型比较方便,作为客户端使用.p12/.jks比较方便),将生成的证书进一步转换。

2.3 证书类型转换

# 根证书crt转p12需要密码

openssl pkcs12 -export -in root.crt -inkey root.key -out root.p12

# 服务端证书crt转p12需要密码

openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12

# p12转jks需要密码(实际项目中可以不用,仅做测试)

keytool -importkeystore -srckeystore root.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore root.jks

生成的全部文件如下:

使用java实现:服务端需要server.p12文件,客户端需要root.p12文件。可以有其他不同的实现方式,需要不同类型的文件可以通过openssl或者keytool进行证书格式转化。(jks格式只是用来测试实际项目中可以不生成)。

3、自签证书的使用

3.1 服务端配置

1、证书放到resources目录下(其他目录也可以,配置文件中写好对应路径就行)

2、在application中添加配置

# 新增http端口

server.port=8075

# 证书路径resource下

server.ssl.key-store=classpath:server.p12

# 密码

server.ssl.key-store-password=hcm@123++

# 服务端限定加密算法

server.ssl.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

# 服务端限定TLS版本

server.ssl.protocol=TLSv1.2

根据实际项目中,客户端和服务端都限定使用这两种算法。

3、配置之后启动项目,之前的端口就是https端口了,这样就不能使用http访问了,需要使用以下代码同时支持http。

//配置http

@Bean

public ServletWebServerFactory servletContainer() {

TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();

tomcat.addAdditionalTomcatConnectors(createStandardConnector());

return tomcat;

}

private Connector createStandardConnector() {

Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");

connector.setPort(“需要使用的http端口”);

return connector;

}

启动项目出现一个http端口一个https端口就是端口开启成功了

可以写个测试方法测试一下

可以看出http和https均可以访问,至此服务端配置完成并且测试通过。

3.2 客户端配置

客户端配置有两种方案,其一是把根证书导入到jdk中,其二就是本次使用的代码实现。

由于不太了解导入到jdk是不是有隐患,所有对第一种方案并没有深入研究,简单的导入命令如下

# 添加cacerts:

keytool -import -v -trustcacerts -alias 1 -file "C:\Users\zhouyinhang\Desktop\fsdownload\testca1\root.crt" -keystore "G:\Program Files\java\jdk1.8.0_181\jre\lib\security\cacerts"

# 查看cacerts中的证书列表:

keytool -list -keystore "C:\Program Files\Java\jre1.8.0_181\lib\security\cacerts" -storepass changeit

# 删除cacerts中指定名称的证书:

keytool -delete -alias 1 -keystore "G:\Program Files\java\jdk1.8.0_181\jre\lib\security\cacerts" -storepass changeit

其中-alias 1 “1”为别名可以通过命令keytool -list -v -keystore root.p12查看,需要注意的是导入jdk的证书格式不可以是p12或者jks格式,可以使用最先生成的crt格式。

下面主要介绍第二种通过代码实现客户端根证书的使用。

通过代码实现主要构造httpClient类

httpClient类作用就是通过记载根证书、密码、配置TLS版本、配置支持的加密套件、配置是否域名效验返回一个CloseableHttpClient连接对象,使用该对象可以直接请求https服务端接口,也可以对CloseableHttpClient对象封装成ReatTemplate。具体实现可以参考源码

下面代码是核心代码,包括如何建立SSLContext连接,TrustManager如何创建。

其中初始化SSLContext是传入三个参数分别是keyManagers(授权的秘钥管理器,用来验证授权),trustManagers(被授权的证书管理器,用来验证服务端证书),secureRandom(随机数,可以填null,SSLContext内部有实现)。项目中cac组件作为客户端时,而且是单向认证所以只需要传第二个参数即可。

public static CloseableHttpClient initSSLConfig() throws Exception {

//证书类型

KeyStore keyStore = KeyStore.getInstance("PKCS12");

//加载根证书

keyStore.load(new FileInputStream(PATH),PASSWORD.toCharArray());

// 创建信任库管理工厂实例

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");

// 初始化信任库

trustManagerFactory.init(keyStore);

TrustManager[] tm = trustManagerFactory.getTrustManagers();

// 建立TLS连接

SSLContext sc = SSLContext.getInstance("TLSv1.2");

         // 初始化SSLContext

sc.init(null,  tm, null);

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(

sc,

// 指定TLS版本

new String[]{"TLSv1.2"},

// 指定算法

new String[]{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},

// 取消域名验证

new HostnameVerifier(){

@Override

public boolean verify(String string, SSLSession ssls) {

return true;

}

}

);

CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

return httpClient;

}

使用同一套证书测试结果

测试不同证书时候,有两种选择,其一把其他根证书签发的服务端证书放到请求的服务器上。其二客户端使用其他的根证书。(根证书和服务器证书不匹配)

错误信息如图

由此可以看出客户端已经使用根证书效验服务端返回的证书了。

demo只是作为测试使用,具体使用要结合实际项目。例如cac组件中基线没有用restTemplate,如果使用restTemplate的话改动太大,只能使用client直接发起请求的方式。

4、正确使用HTTPS

虽然在通信中有必要使用HTTPS,但是不能全部通信都使用,原因主要有两点:

  • HTTPS需要认证,所以相对于HTTP来说效率肯定是比较慢的。
  • 要进行HTTPS通信,必须要有证书,这些证书一般都需要向认证机构购买。

java实现HTTPS单向认证&TLS指定加密套件的更多相关文章

  1. JAVA实现https单向认证

    //关于http 须要两个jar包 httpclient-4.0.jar httpcore-4.0.1.jar private static final HttpClient httpClient = ...

  2. java https单向认证(忽略认证)并支持http基本认证

    https单向认证(忽略认证)并支持http基本认证, 温馨提示 1,jar包要导入对 2,有匿名类编译要注意 3,欢迎提问,拿走不谢!背景知识 Https访问的相关知识中,主要分为单向验证和双向验证 ...

  3. Tomcat添加HTTPS单向认证和双向认证

    前言 前一段时间有了解如何配置Tomcat服务为Https单向认证和双向认证,当时也做了一些记录,今天开始写博客,就把以前的记录拿出来整理下,分享给大家.本文没有介绍证书如何生成,会在下一篇博文里介绍 ...

  4. https 单向认证和双向认证配置

    HTTPS 是我们开发中经常用到的通信加密技术,能有效保护我们网络访问中的安全,本文主要讲解单向 和 双向 https 的配置.关于https 的实现原理在这里我就不赘述了,附上阮一峰老师的关于htt ...

  5. tomcat 配置https (单向认证)

    1.单向认证,就是传输的数据加密过了,但是不会校验客户端的来源 2.双向认证,如果客户端浏览器没有导入客户端证书,是访问不了web系统的,找不到地址 如果只是加密,单向就行 如果想要用系统的人没有证书 ...

  6. Rest接口加Https单向认证

    背景: 接到一个需求,客户要求某个模块的rest接口都得通过https访问,客户提供证书. 步骤: Server端证书生成 刚开始还没拿到客户的证书,所以通过jdk自带的keytools自己先生成了一 ...

  7. Https单向认证和双向认证介绍

    一.Http HyperText Transfer Protocol,超文本传输协议,是互联网上使用最广泛的一种协议,所有WWW文件必须遵循的标准.HTTP协议传输的数据都是未加密的,也就是明文的,因 ...

  8. 图解 https 单向认证和双向认证!

    来源: 一.Http HyperText Transfer Protocol,超文本传输协议,是互联网上使用最广泛的一种协议,所有WWW文件必须遵循的标准.HTTP协议传输的数据都是未加密的,也就是明 ...

  9. https单向认证和双向认证

    单向认证: .clinet<--server .clinet-->server .client从server处拿到server的证书,通过公司的CA去验证该证书,以确认server是真实的 ...

随机推荐

  1. SRGAN

    目录 概 主要内容 代码 Ledig C., Theis L., Huszar F., Caballero J., Cunningham A., Acosta A., Aitken A., Tejan ...

  2. matplotlib 高阶之Transformations Tutorial

    目录 Data coordinates Axes coordinates Blended transformations 混合坐标系统 plotting in physical units 使用off ...

  3. CS5210完全替代AG6202|HDMI转VGA芯片+原理图|替代兼容AG6202

    安格AG6202是一个HDMI转VGA不带音频解决方案,用于实现HDMI1.4高分辨率视频转VGA转换器.Capstone  CS5210不管在性能上和设计参数上面都是可以完全替代安格AG6202,且 ...

  4. JDK HttpClient 单次请求的生命周期

    HttpClient 单次请求的生命周期 目录 HttpClient 单次请求的生命周期 1. 简述 2. uml图 3. Http连接的建立.复用和降级 3.1 调用流程及连接的建立和复用 3.2 ...

  5. Java中关于super关键字的作用

    在子类继承父类中,一般有一行super的语句,需要记住三种使用方法: 1.super.变量/对象名: 使用这种方法可以直接访问父类中的变量或对象,进行修改赋值等操作 2.super.方法名(): 直接 ...

  6. 数据库SQL语言类型(DQL.DML.DDL.DCL)

    1.SQL语言 SQL(Structure Query Language)语言是数据库的核心语言. SQL是一个标准的数据库语言, 是面向集合的描述性非过程化语言. 它功能强,效率高,简单易学易维护. ...

  7. Linux_grep命令

    搜索内容 命令格式如下 grep 参数 "搜索的内容" 搜索路径 注:搜索路径可缺省,缺省时,默认搜索当前目录以及其子目录下所有文件 显示文件名+内容: grep -r " ...

  8. Windows alias 给cmd命令起别名

    场景: Linux的alias命令是个非常实用的工具,任何命令通过alias可以精简到很短,比如:alias l='ls -l' Windows也有alias类似的命令,就是:doskey,开启方法也 ...

  9. react中使用immutable

    官方文档(https://immutable-js.github.io/immutable-js/docs/#/) 有人说 Immutable 可以给 React 应用带来数十倍的提升,也有人说 Im ...

  10. Centos安装rrdtool的yum源

    由于centos的标准组件中是不带rrdtool的,因此我们需要添加一个dag的yum源,以安装rrdtool. 修改/etc/yum.repos.d/CentOS-Base.repo, #vi /e ...