首页 > 其他分享 >HTTPS双向认证【转】

HTTPS双向认证【转】

时间:2023-04-06 15:11:56浏览次数:26  
标签:key certificate 证书 server ssl client 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.crtserver.p12server.crtserver.keyclient.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 authentication
            ClientCertificateMode = 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 certificate
        var 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 certificate
        return 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 certificate
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;

# root certificate
ssl_client_certificate /etc/nginx/ssl/ca.crt;
# open client certificate verify
ssl_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

标签:key,certificate,证书,server,ssl,client,HTTPS,双向,认证
From: https://www.cnblogs.com/fanfan-90/p/17292817.html

相关文章

  • 成功解决requests 报错raise SSLError(e, request=request)_requests.exceptions.SSL
    问题描述在使用requests调用https接口时,会遇到ssl证书报错raiseSSLError(e,request=request)requests.exceptions.SSLError:HTTPSConnectionPool(host='v4.ketangpai.com',port=443):Maxretriesexceededwithurl:/UserApi/login(CausedbySSLError(SSLCertVerificat......
  • JWT 实现登录认证 + Token 自动续期方案
    要实现认证功能,很容易就会想到JWT或者session,但是两者有啥区别?各自的优缺点?应该Pick谁?夺命三连区别基于session和基于JWT的方式的主要区别就是用户的状态保存的位置,session是保存在服务端的,而JWT是保存在客户端的认证流程基于session的认证流程用户在浏览器中输入用户名和密码,服务......
  • HTTPS协议概述&HTTPS使用成本&HTTPS对性能的影响&HTTPS常见问题
    HTTPS协议概述 HTTPS可以认为是HTTP+TLSTLS是传输层加密协议,它的前身是SSL协议  HTTPS功能介绍内容加密1、非对称密匙交换2、对称内容加密身份认证1、数字证书数据完整性HTTPS使用成本证书费用以及更新维护HTTPS降低用户访问速度消耗CPU资源,需要增加大量......
  • TCP/IP和OSI的基础层级关系图,TCP/IP四层模型关系,TCP/IP和HTTP/HTTPS的关系图
    TCP/传输控制协议英文全称TransmissionControlProtocol。IP/网际互连协议英文全称InternetProtocol。tcp和ip是互联网众多通信协议中最为著名的。1.OSI参考模型与TCP/IP的关系计算机网络分层模型OSI七层模型TCP/IP四层模型TCP/IP五层模型应用层应用层应用层......
  • Redis 在身份认证中的应用
    1.Redis在Session共享问题中的应用传统Session-Cookeis身份认证方法中,一个Session只保存在一台服务器上,适合域单体应用。随着项目规模的增加,项目的架构也不断向微服务分布式集群演进,传统的Session-Cookie方式在集群环境下就不能很好的工作了,这时就产生了Session共......
  • 6·2HTTPS协议概述|6·32HTTPS使用成本|6·42HTTPS对性能的影响|6·52HTTPS常见问题
    HTTPS可以认为是HTTPS+TLSTLS是传输层加密协议,它的前身是SSL协议HTTPS功能介绍 内容加密 非对称密钥交换 对称内容加密 身份认证 数字证书 数据完整性 HTTPS使用成本 证书费用以及更新维护 HT......
  • [!] CDN: trunk URL couldn‘t be downloaded: https://cdn.jsdelivr.net/cocoa/
    热烈欢迎,请直接点击!!!进入博主AppStore主页,下载使用各个作品!!!注:博主将坚持每月上线一个新app!!!清华CocoaPods镜像源:CocoaPods镜像使用帮助CocoaPods是一个Cocoa和CocoaTouch框架的依赖管理器,具体原理和Homebrew有点类似,都是从GitHub下载索引,然后根据索引下载依赖的源......
  • 秒懂HTTPS接口(实现篇)
    HTTPS接口实现下面我们来实践使用Java实现一个简单HTTPS接口示例项目结构:1.springbootdemo2.├─config配置信息类3.├─controller控制器类4.├─entity实体类5.├─enums枚举类6.├─exception异常类7.├─handler捕获类8.├─repository数据访问类9.├......
  • 单向链表和双向链表的逆序的两种实现方式
    单向链表的逆序实现方式publicstaticclassNode{privateintval;privateNodenext;publicNode(intval){this.val=val;}}/**实现单向链表的第一种方式,只通过链表指针的重连来实现*/publicstaticNoderece......
  • 复验、见证取样检验、型式检验与3C认证 (知识点)
    GB50411-2019规定,术语2.0.8 复验 sitereinspection(repeattest)  进入施工现场的材料、设备等在进场验收合格的基础上,按照有关规定从施工现场随机抽样,送至具备相应资质的检测机构进行部分或全部性能参数检验的活动。  2.0.9 见证取样检验 witnesssamplinginspe......