聊一聊HTTPS双向认证的简单应用
背景
在三方接口对接中,偶尔会遇到需要传递证书的情况,这种方式其实是在SSL握手过程中会同时验证客户端和服务器的身份,这就是我们常说的 双向认证。
双向认证需要服务器和客户端提供身份认证,只能是服务器允许的客户方能访问,安全性相对于要高一些。
下面老黄用几个小例子来演示一下双向认证的简单应用。
准备工作
由于离不开证书,所以我们需要提前生成好几个证书,这里用 OpenSSL 来生成一个自签名的。
2 个根证书,1 个服务端证书,2个不是同一个根证书下面的客户端证书
# 根证书
openssl genrsa -out ca.key 4096
openssl req -new -key ca.key -out ca.csr -days 365
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt -days 365# 服务端证书
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr -days 365
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12# 客户端证书
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr -days 365
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12
最后会有下面几个文件要在后面的演示中用到:ca.crt
、server.p12
、server.crt
、server.key
、client.p12
和 client2.p12
。
下面先来看看 ASP.NET Core 直接对外的情况,也就是不依赖 nginx 或 IIS 的情况。
ASP.NET Core
基于 minimal api 来演示,主要是在 ConfigureKestrel 做处理。
var builder = WebApplication.CreateBuilder(args);builder.WebHost.ConfigureKestrel(x =>
{x.Listen(IPAddress.Any, 443, listenOptions =>{var serverCertificate = new X509Certificate2("server.p12", "abc123");var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions(){// must provide a valid certificate for authenticationClientCertificateMode = ClientCertificateMode.RequireCertificate,SslProtocols = System.Security.Authentication.SslProtocols.Tls12,ClientCertificateValidation = (cer, chain, error) =>{// valid the client certificate by you way.return CusSSLLib.CaHelper.Valid(cer, chain, error);},ServerCertificate = serverCertificate};listenOptions.UseHttps(httpsConnectionAdapterOptions);});
});
这里最核心的是 HttpsConnectionAdapterOptions。
ServerCertificate 设置成我们上面生成的服务端证书。
ClientCertificateMode 设置成 RequireCertificate,表示客户端在调用的时候必须要传递证书。
ClientCertificateValidation 就是验证客户端证书的逻辑,这里可以自定义,示例里面的验证逻辑主要针对不被信任的根证书做了验证。
首先是从资源文件读取了根证书,然后再去判断客户端证书是否匹配。
到这里的话,服务端已经可以了。
这个时候从浏览器访问,大概会看到这个提示。
下面写个控制台用 HttpClient 来访问看看。
void DoOk()
{var handler = new HttpClientHandler();handler.ClientCertificateOptions = ClientCertificateOption.Manual;handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls | SslProtocols.None | SslProtocols.Tls11;try{// add client certificatevar crt = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "client.p12"), "123456");handler.ClientCertificates.Add(crt);}catch (Exception e){Console.WriteLine(e.Message);}handler.ServerCertificateCustomValidationCallback = (message, cer, chain, errors) =>{// valid server certificatereturn CusSSLLib.CaHelper.Valid(cer, chain, errors);};var client = new HttpClient(handler);var url = "https://localhost/WeatherForecast";var response = client.GetAsync(url).Result;Console.WriteLine(response.IsSuccessStatusCode);var result = response.Content.ReadAsStringAsync().Result;Console.WriteLine(result);
}
这里要注意,由于服务端用的证书也是自己签名的,所以这里的验证也要放开,想省事的话,可以直接 return true;
,不过并不建议这样操作。
下面是运行的结果,是可以正常访问并返回结果的。
我们再换一张不是同一个根证书的客户端证书。
不出意外的不能正常访问。
不过上面这种情况在实际应用的时候会偏少一点,大部分还是会挂在反向代理或云负载均衡上面的。
下面先来看看 nginx 的吧。
nginx 反向代理
webapi 这一块,创建一个项目,有一个可以访问的接口即可,不用添加其他东西,因为证书这一块的内容都是在 nginx 那一层做了,webapi做原来该做的事情即可。
下面是 nginx 的配置文件
server {listen 443 ssl;server_name localhost;# server certificatessl_certificate /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key;# root certificatessl_client_certificate /etc/nginx/ssl/ca.crt;# open client certificate verifyssl_verify_client on;ssl_session_timeout 5m; location / {proxy_pass http://webapi;index index.html;}}
重点关注 ssl_verify_client 和 ssl_client_certificate !
一个是配置开启客户端证书的认证,一个是验证的客户端证书的关键。
这里的 ssl_client_certificate 用了根证书,为的是可以验证多个客户端证书,当然这里也可以用客户端证书。
把 webapi 和 nginx 都运行起来。
这个时候访问,就会提示, No required SSL certificate was sent。
用上面的控制台,再访问看看。
正确的证书,可以正常返回,错误的证书会返回 400 The SSL certificate error。
基于反向代理的话,操作起来就简单了一点。
如果是云负载均衡,只需要按他们的要求上传对应的证书即可。
讲了 nginx,不讲讲 IIS,好像有点说不过去。
那就再看看 IIS 的配置吧。
IIS 部署
在 Windows 服务器安装好 IIS 和托管捆绑包后,要先把我们的根证书安装到可信的根证书里面。
然后进行部署,绑定好服务端证书后,确认可以正常访问。
然后进行双向认证的配置。
在对应站点上面的 SSL 配置
,把 要求 SSL
和 必需
两个勾上即可。
后面再访问的时候,就会提示选择证书
选择正确的证书后就可以正常访问了。
然后我们再用前面的控制台程序访问,结果如下。
可以发现和前面的结果是一样的,不同的是错误返回的内容不一样。
上面提到的都是一些自建的场景,其实对云负载均衡的结合使用也是 OK 的。
总结
双向认证,在一些安全要求比较高的场景下,用途还是比较大的,相比较单向认证的话会麻烦一些。
参考资料
https://michielsioen.be/2020-10-17-mutual-ssl-linux/
https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/
https://learn.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis
聊一聊HTTPS双向认证的简单应用相关推荐
- TurboMail邮件系统支持HTTPS双向认证
2019独角兽企业重金招聘Python工程师标准>>> HTTP单向认证已经被普遍应用,而对企业邮箱安全保密要求更加严格的企事业单位,例如国家保密局等单位,为了达到闭环的安全加密要求 ...
- 巧用 Nginx 快速实现 HTTPS 双向认证
1.原理 双向认证,顾名思义,客户端和服务器端都需要验证对方的身份,在建立 HTTPS 连接的过程中,握手的流程比单向认证多了几步.单向认证的过程,客户端从服务器端下载服务器端公钥证书进行验证,然后建 ...
- HTTPS双向认证(Mutual TLS authentication)
HTTPS双向认证(Mutual TLS authentication) 双向认证,顾名思义,客户端和服务器端都需要验证对方的身份,在建立Https连接的过程中,握手的流程比单向认证多了几步.单向认证 ...
- https 双向认证开发实践
https双向认证 证书如何使用 一.概念介绍 1.https协议介绍 与http协议的区别 https协议简单来说就是http协议的基础上增加了SSL协议 ,从而来保证数据传输的安全性. SSL协议 ...
- tomcat实现https双向认证配置
Tomcat实现https双向认证配置 1.生成证书库 2.jks转p12 3.证书库导出cer文件 4.证书库生成证书请求 5.对证书请求进行签名 6.例子 6.1创建证书库 6.2导出根证书 6. ...
- Ktor实现Https双向认证
前言 Ktor依靠跨端的能力,使得我们可以统一前后端.多平台的网路开发体验,本篇讲解如何在Ktor中实现Https双向认证. 密钥库 双向认证简单来说就是前后端各自生成自己的密钥库(包含一对公私钥), ...
- Https双向认证Android客户端配置
Https双向认证啊 做了两遍,第一遍懵懂状态处于 好不容易做好了,换服务器,一下子懵了,使出浑身解数又找了一遍,这下终于好了 快哭啦,必须滴要记录一下,以免以后遇到继续懵,这里用retrofit ...
- Spring实现HTTPS双向认证
目录 前言 一.单向认证和双向认证 二.创建keyStore和trustStore 三.服务端配置 四.客户端配置 总结 参考链接 前言 本篇博客讲的主要是双向认证,通过一些简单案例来展示双向认证的配 ...
- android webview单向认证,android 让webview支持自签名证书https 双向认证(SSL)
最近完成一个项目,安全级别比较高.所以涉及到https双向认证,在网上找了很多资料都没有完美的解决方案.最后参考了org.sandrob.sslexample的实现方式,结合实际情况才完成该技术难题, ...
最新文章
- 任意多相机系统的SLAM重设计
- 归一化 vs 标准化 定量的分析
- 关于lucene的书
- 学习Java编程-Java Timezone类常见问题
- 【学习笔记】MOOC 数学文化赏析 笔记
- Android 编码规范:(五)避免创建不必要的对象
- python中getattr()的用法
- LeetCode 73. Set Matrix Zeroes
- Deep Learning ——Yann LeCun,Yoshua BengioGeoffrey Hinton
- JavaSE——Java8之Stream流
- dreamweaver代码提示失效
- python 物理引擎_第十六章:物理引擎
- 静态测试和动态测试有何区别
- OpenCV每日函数 WeChat QR 微信二维码检测器
- Python实现的简易HTTP代理服务器
- 最全的人力资源行业精美报表模板,免费下载啦
- 北京科技大学计算机专业在哪个校区,北京科技大学有几个校区及校区地址
- 玩个游戏好难 Win10我的世界(Minecraft)下载
- 手机原来也能把照片制作成视频?1分钟包你学会,发朋友圈超有范
- 【分布式任务调度】(三)XXL-JOB调度中心对执行器的上下线感知实现原理