1. 准备域名
既然是白嫖,那么域名我们就使用免费的域名就好了,我在freenom网站上注册的。免费的都是比较偏的域名后缀,不过无所谓,反正测试用而已
做好域名解析,我这里本地测试使用,所以解析到自己的内网ip(能指向本机就行啦)
2. 准备https证书
CA证书的话,有两种选择,一种使用自签名证书,一种使用CA官方证书;
区别:
- 自签名证书是“黑户”,只能起到https加密的作用,但是无法被浏览器、操作系统承认
- 具体效果就是浏览器访问时会显示“不安全连接”的图标和提示
- 自签名证书无法防范“中间人攻击”方式,其实还是不安全的通信方式(客户端的可以自己去实现加密通信策略)
- 使用CA证书需要付费,并且有时限,要考虑成本和注意到期续费问题(过期的CA证书等同于自签名证书)
2.1 免费CA证书申请
免费的CA证书申请渠道很多,基本是1年期限,我这里使用freessl,注册流程忽略,没什么好说的(其中一步域名验证,只要做好相关解析,等解析生效验证过关即可)
2.1.1 生成CA证书
申请成功后,可以启动网站提供的客户端“keyManager”,在“证书管理--选中某个证书--更多--所有格式--输入私钥加密密码--导出”
导出后有多个文件夹,对应不同的web服务器,我将使用tomcat服务器,所以选用“.jks”后缀的私钥
3. 准备java web项目
我这里准备了个简单的spring boot项目,写了一个简单的接口,用于后续移动端https请求用
核心代码
入口类
package com.lawyee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class AppBoot extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AppBoot.class);
}
// spring boot项目部署到独立的tomcat服务器上,需要继承SpringBootServletInitializer类,重写配置资源路径方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(AppBoot.class);
}
}
准备接口
package com.lawyee.controller;
import com.lawyee.domain.Order;
import com.lawyee.domain.ResVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
@RequestMapping("/findById")
public ResVo findOne(String sn) {
if (null == sn) {
log.error("查询订单号为空");
return new ResVo(0, "查询订单号为空", null);
}
if (sn.length() < 6) {
log.warn("订单号不能小于6位");
return new ResVo(0, "订单号不能小于6位", null);
}
Order order = new Order(sn, new Date(), "雅迪电动车");
ResVo resVo = new ResVo(1, "查找到1个符合订单", order);
log.debug("查询出1个结果,订单号:{},详细信息:{}", sn, order);
return resVo;
}
}
4. 准备https的web服务器
- 我这里使用
apache-tomcat-8.5.31
做web服务器,从官网下载即可; - 把之前第二步中生成的CA证书tomcat目录下,
.jks
后缀的文件,拷贝到tomcat根目录下的conf
文件夹中 - 将第三步中的java web工程,打包成war包,拷贝到tomcat根目录下的
webapps
文件夹中 - 修改
conf
文件夹下的server.xml
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
<Service name="Catalina">
<!-- 使用80接口,指定跳转到443接口,https默认接口 -->
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="443"/>
<!-- 配置https,默认接口443,keystoreFile指定私钥文件路径, keystorePass指定私钥密码-->
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="conf/lixian.jks"
keystorePass="123456"
clientAuth="false" sslProtocol="TLS" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector URIEncoding="UTF-8" port="8009" protocol="AJP/1.3" redirectPort="8443"/>
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt"/>
</Host>
</Engine>
</Service>
</Server>
- 修改
conf
文件夹下的web.xml
配置文件,让访问http也跳转到https,在文件最后,添加以下配置代码
<login-config>
<!-- Authorization setting for SSL -->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<!-- Authorization setting for SSL -->
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
- 启动服务器后,使用证书对应的域名访问,浏览器地址栏左侧会显示一个锁的图标,点击开来会显示
连接是安全的
;(如果使用本地ip或者其他解析的域名,或者自签名证书,这里一样是显示不安全的链接) - 注意:CA证书、证书对应的域名必须一致(包括记录值,除非你的证书是*通配的<通配的证书很贵的>)
5. 奉上以上文件
6. 客户端请求看效果
这里用iOS客户端发起请求,再用青花瓷抓包看看https通信的效果
6.1 准备OC网络请求代码
[[AFHTTPSessionManager manager] GET:@"https://www.lixian.ml/addr/order/findById" parameters:@{@"sn": @"6666231"} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"responseObject = %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error = %@", error);
}];
6.2 用青花瓷抓包
https抓包效果:通信自动被加密
http抓包效果:通信未加密,全是明文