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. 使用.NET 6开发TodoList应用(11)——使用FluentValidation和MediatR实现接口请求验证

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在响应请求处理的过程中,我们经常需要对请求参数的合法性进行校验,如果参数不合法,将不继续进行业务逻辑的处理.我们当然可以将每个 ...

  2. MacOS使用IDEA+Maven+Scala+Spark进行本地调试

    参考:spark开发环境搭建(基于idea 和maven) 安装JDK 从这里下载Java 8的JDK 设置JAVA_HOME环境变量,在Mac上它大概会是/Library/Java/JavaVirt ...

  3. python 脚本或者flask 注册成为windows服务

    分享下脚本注册成为win服务 这个借鉴了其他大佬得 具体是谁忘记了有机会推荐 今天也是找了之前得改出来得 首先安装三个模块 最后一个是定时任务如果不需要可以不装 pip install psutil ...

  4. IPv6地址格式

    1.说明 IPv6是互联网协议的第六版, 现有IPv4只支持大概40亿个网络地址, 而IPv6支持3.4e38个网络地址. IPv4的地址长度是32位(bit), IPv6的地址长度是128位. 尽管 ...

  5. Java常用的几种设计模式

    本来想写点spring相关的东西的,想来想去,先写点设计模式的东西吧 什么是设计模式?套用百度百科的话解释吧 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设 ...

  6. centos6.5-搭建Apache-地址限制和用户访问

    对于企业内部的WEB管理平台,例如日志分析系统(Awstats)为了更好实现访问控制,在通过客户端访问时,提交一些用户密码或对客户IP地址进行授权,避免服务器的安全隐患. 常见的访问控制方式:应用于配 ...

  7. MongoDB高级应用之数据转存与恢复(5)

    1.MongoDB索引 1.1.创建索引 db.books.ensureIndex{{number:1}} 创建索引同时指定索引的名字 db.books.ensureIndex({number:1}, ...

  8. 深入研究 synchronized 同步锁 作用于 静态方法 和 非静态方法 的 区别

    1.前言 众所周知, synchronized 是同步锁 ,虽然在底层又细分了无锁.偏向锁.轻量级锁.自旋锁 以及重量级锁 机制, 这些底层锁知道一下原理即可 ,[想要 了解 这篇 博文 有 解释 : ...

  9. “老”的Flexbox和“新”的Flexbox

    本文由大漠根据Chris Coyier的<"Old" Flexbox and "New" Flexbox>所译,整个译文带有我们自己的理解与思想,如 ...

  10. Unity3D开发入门教程(三)——添加启动脚本

    五邑隐侠,本名关健昌,12年游戏生涯. 本教程以 Unity 3D + VS Code + C# + tolua 为例. 一.启动脚本 第一篇 "搭建开发环境",在 "配 ...