关于https双向认证的知识可先行google,这时矸接代码。

为了双向认证,我们首先得准备两个crt证书,一个是client.crt,一个是server.crt,有时为了验证是否同一个根证书的验证,这两个证书可以共有一个根证书root.crt。

首先要生成这些证书,这里采用了自签证书方式:

证书生成工具可在这里下载(windows下生成):

https://github.com/axzxs2001/Asp.NetCoreExperiment/blob/master/Asp.NetCoreExperiment/Certificate/openssl/Win64OpenSSL-1_1_0i.exe

安装完成后在C:\OpenSSL-Win64\bin(最好不要改路径,否则生成证书时要改配置文件路径)下以管理员运行openssl.exe

一、创建根证书

  • 生成key文件,输入密码:

  openssl genrsa -des3 -out root.key

  • 生成请求证书文件,如果安装路径发生改变,可以通过在下面命令后面添加-config openssl.cfg来指明配置文件路径

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

  • 生成一个10年期根证书 root.crt:

  openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey root.key -in root.csr -out root.crt

  分别在客户端或服务端安装根证书,windows上安装证书时,证书存储可选择“受信任的根证书颁发机构”

 

二、创建服务端证书

  • 生成key文件,输入密码

  openssl genrsa -des3 -out server.key 2048

  • 生成请求证书文件,如果安装路径发生改变

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

  • 用根证书生成一个10年期证书 server.crt:

  openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA root.crt -CAkey root.key -CAserial root.srl -CAcreateserial -in server.csr -out server.crt

  • 生成.net core识别的证书文件server.pfx

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

三、创建客户端证书

  • 生成key文件,输入密码

  openssl genrsa -des3 -out client.key 2048

  • 生成请求证书文件,如果安装路径发生改变

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

  • 用根证书生成一个10年期证书 client.crt:

  openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA root.crt -CAkey root.key -CAserial root.srl -CAcreateserial -in client.csr -out client.crt

  • 生成.net core识别的证书文件client.pfx

  openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx

接下来创建asp.net core web api项目,并把server.pfx添加到项目中,并设置属性为“始终复制”,接着修改Program.cs下的CreateWebHostBuilder方法就可以:

   public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.Listen(IPAddress.Any, );
//启用https,443端口
options.Listen(IPAddress.Any, , listenOptions =>
{
var serverCertificate = new X509Certificate2("server.pfx", "ssssss");
var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions()
{
ClientCertificateMode = ClientCertificateMode.AllowCertificate,
SslProtocols = System.Security.Authentication.SslProtocols.Tls12,
//用chain.Build验证客户端证书
ClientCertificateValidation = (cer, chain, error) =>
{
return chain.Build(cer);
},
ServerCertificate = signingCertificate
};
listenOptions.UseHttps(httpsConnectionAdapterOptions);
});
})
.UseStartup<Startup>();

为了区分http和https请求,在HomeController中写如下代码:

         [HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
var cer = HttpContext.Connection.ClientCertificate;
//证书为空,返回BadRequest
if (cer == null)
{
return BadRequest();
}
else
{
return new string[] { "value1", "value2" };
}
}

创建客户应用,.net core的控制台项目,把client.pfx添加到项目中,并设置属性为“始终复制”,然后代码如下

         static void Main(string[] args)
{
Console.WriteLine("enter start");
while (true)
{
try
{
Console.WriteLine("1、Https 2、Http");
switch (Console.ReadLine())
{
case "":
HttpsMethod();
break;
case "":
HttpMethod();
break;
}
void HttpsMethod()
{
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls | SslProtocols.None | SslProtocols.Tls11;
try
{
//加载客户端证书
var crt = new X509Certificate2(Directory.GetCurrentDirectory() + "/client.pfx", "cccccc");
handler.ClientCertificates.Add(crt);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//用chain.Build验证服务器证书
handler.ServerCertificateCustomValidationCallback = (message, cer, chain, errors) =>
{
return chain.Build(cer);
};
var client = new HttpClient(handler);
var url = "https://192.168.252.41 /api/values";
var response = client.GetAsync(url).Result;
Console.WriteLine(response.IsSuccessStatusCode);
var back = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(back);
}
void HttpMethod()
{
var client = new HttpClient();
var url = "http://192.168.252.41/api/values";
var response = client.GetAsync(url).Result;
Console.WriteLine(response.IsSuccessStatusCode);
var back = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(back);
}
}
catch (Exception exc)
{
Console.WriteLine(exc.InnerException?.InnerException?.Message);
}
}
}

结果如下图:

代码:https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/Certificate

.net core下用HttpClient和asp.net core实现https的双向认证的更多相关文章

  1. ubuntu16.4下用jexus部署asp.net core rtm

    上篇文章介绍了下用vs发布部署到iis环境,今天说下ubuntu 下部署asp.net core,不需要安装.net core sdk,自带运行时方式部署,利用jexus服务器转发请求到asp.net ...

  2. 在Linux环境下使用Jexus部署ASP.NET Core

    关于如何在Linux中添加ASP.NET Core运行时环境请参考我的上一篇文章,本文章将不再做赘述. 本文章运行环境如下:  (1) 安装独立版Jexus 本教程安装的是独立版的Jexus,独立版的 ...

  3. 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】

    Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...

  4. 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门

    一.前言 1.本教程主要内容 ASP.NET Core 中间件介绍 通过自定义 ASP.NET Core 中间件实现请求验签 2.本教程环境信息 软件/环境 说明 操作系统 Windows 10 SD ...

  6. C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理

    C#编译器优化那点事   使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的.优化代码 ...

  7. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

  8. ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 编辑表单 上一章节我们介绍了标签助手和 HT ...

  9. ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 设置和初始化数据库 上一章节中我们已经设置和配置好了 EF ...

随机推荐

  1. 微服务架构:Eureka参数配置项详解

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! Eureka涉及到的参数配置项数量众多,它的很多功能都是通过参数配置来实现的,了解这些参数的含义有助于我们更好的应用Eureka的各种功能 ...

  2. 服务器配置用户信息、ssh免密码登录和防火墙等安全配置

    一.登录服务器      1.回到根目录 cd ~      2.ssh + 用户名@服务器公网地址 ssh root@47.94.208.76      3.输入密码:注意输入法大小写 二.查看服务 ...

  3. rand函数

    srand()用来初始化随机数种子,rand()用来产生随机数 srand(time()); while(t--){ printf("-> %d %d\n",rand(),r ...

  4. Scrapy爬虫错误日志汇总

    1.数组越界问题(list index out of range) 原因:第1种可能情况:list[index]index超出范围,也就是常说的数组越界. 第2种可能情况:list是一个空的, 没有一 ...

  5. C# /VB.NET操作Word批注(一)—— 插入、修改、删除Word批注

    批注内容可以是对某段文字或内容的注释,也可以是对文段中心思想的概括提要,或者是对文章内容的评判.疑问,以及在阅读时给自己或他人起到提示作用.本篇文章中将介绍如何在C#中操作Word批注,主要包含以下要 ...

  6. Java基础:HashMap中putAll方法的疑惑

    最近回顾了下HashMap的源码(JDK1.7),当读到putAll方法时,发现了之前写的TODO标记,当时由于时间匆忙没来得及深究,现在回顾到了就再仔细思考了下 @Override public v ...

  7. asp.net DES加密解密

    数据加密标准DES加密算法是一种对称加密算法,DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小.这是一个迭代的分组密码,使用称为 Feistel 的技术,其中 ...

  8. C#面试分享:单例模式

    C#面试分享:单例模式 提问1:请给出单例模式的实现: 答: public class Animal { private static Animal _instance = null; private ...

  9. linux学习笔记-linux主机上传下载文件至linux虚拟机的方法

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 1.上传文件 scp -r file 用户名@ip地址:目标目录 2.下载文件 scp -r 用户名@ip地址:文件 目标目录

  10. Linux系统使用

    linux(操作系统的内核) 浏览器功能:(内核的解释) 各个浏览器 实现的方式不一样 呈现内容 //解析内容和样式 用—webkit— (内核)解析 实现交互逻辑 v8 引擎 (内核) 实现 =&g ...