ASP.NET Core – Work with X509
前言
这篇主要是说如何用 ASP.NET Core 读写系统里的证书 Store 和创建一个证书, 还有使用证书做加密, 解密, 签名.
主要参考:
C#数字证书编程总结 (读写证书 Store)
Encryption and signing credentials (创建证书)
X.509 Store and Create
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); // 也可以从 LocalMachine 拿
store.Open(OpenFlags.ReadWrite); // 如果只是要读, 可以放 ReadOnly
// 查找
// var certificates = store.Certificates.Find(
// X509FindType.FindBySubjectName,
// findValue: "jbreviews.com.my",
// validOnly: false // validOnly 可以检查 expired 和 是否 under root 证书 (self sign 的通常不 under root)
// );
// 遍历
foreach (var certificate in store.Certificates)
{ }
// 制作 certificate
using var algorithm = RSA.Create(keySizeInBits: 2048);
var subject = new X500DistinguishedName($"CN=My signing certification");
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
// X509KeyUsageFlags.DigitalSignature for 签名, X509KeyUsageFlags.KeyEncipherment for 加密
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true));
var newCertificate = request.CreateSelfSigned(
notBefore: DateTimeOffset.UtcNow,
notAfter: DateTimeOffset.UtcNow.AddYears(1)
);
var rowData = newCertificate.Export(X509ContentType.Pfx, "password"); // 添加私钥的保护密码, 因为我们要 store 起来所以需要一个保护密码
newCertificate = new X509Certificate2(rowData, "password", X509KeyStorageFlags.Exportable);
// 添加新的 cert
store.Add(newCertificate);
注意: 要写入 store 的 permission 需要是 admin 等级. 一般上在 production server 是做不到的.

参考: ASP.NET Core app within aspnet:3.1-nanoserver-1809 gets Access Denied on X509Store.Add()
解决方法是 manual import certificate, 设置 OpenFlags.ReadOnly 就好.
然后把做好的 certificate export 成 .pfx, 记得要配置 X509KeyStorageFlags.Exportable 才可以 export 哦.
var certificateBytes = certificate.Export(X509ContentType.Pfx, password);
System.IO.File.WriteAllBytes("Certificate.pfx", certificateBytes);
然后双击一直 next 就可以了.
疑难杂症 in Azure VM
在 production server (Azure VM) 有可能拿不到 CurrentUser 的 certificate. 参考: Can't Get Current User Certificate From X.509 Store
可能是因为 IIS User 的权限问题吧. 解决方法是用 LocalMachine

在实例化 X509 时遇到 Error: The system cannot find the file specified
var certificate = new X509Certificate2(rawData: privateKeyBytes); // Error:The system cannot find the file specified
解决方法之一是 IIS set pool Load User Profile = true
但这个不是很好. 比较好的是这样调用
var certificate = new X509Certificate2(rawData: privateKeyBytes, password: (string?)null, keyStorageFlags: X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.EphemeralKeySet);
原理看这里: What exactly happens when I set LoadUserProfile of IIS pool?
既然 Server store 和 IIS 经常会遇到权限问题, 那也可以改用 Azure KeyVault Certificate Service. 看这篇.
加密, 解密, 签名
参考: Encrypt / Decrypt in C# using Certificate
Public Key 加密, Private Key 解密 (注: 通常非对称加密, 只用来加密对称加密的密钥, 内容要短, 不然很慢的)
签名和验证签名则反过来 Private Key 签名, Public Key 验证. (注: 还需要 SHA256 消息摘要哦)
加密, 解密
using var algorithm = RSA.Create(keySizeInBits: 2048);
var subject = new X500DistinguishedName($"CN=jbreviews");
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true));
var certificate = request.CreateSelfSigned(
notBefore: DateTimeOffset.UtcNow,
notAfter: DateTimeOffset.UtcNow.AddDays(30)
);
var password = "password";
using var privateKey = certificate.GetRSAPrivateKey()!;
using var publicKey = certificate.GetRSAPublicKey()!;
var encryption = publicKey.Encrypt(Encoding.UTF8.GetBytes(password), RSAEncryptionPadding.OaepSHA256);
var decryption = privateKey.Decrypt(encryption, RSAEncryptionPadding.OaepSHA256);
var valid = Encoding.UTF8.GetString(decryption) == password;
request.CertificateExtensions 加不加好像不太重要. 我试过不加也可以正常跑.
签名, 验证签名
using var algorithm = RSA.Create(keySizeInBits: 2048);
var subject = new X500DistinguishedName($"CN=jbreviews");
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true));
var certificate = request.CreateSelfSigned(
notBefore: DateTimeOffset.UtcNow,
notAfter: DateTimeOffset.UtcNow.AddDays(30)
);
var message = "value";
using var sha256 = SHA256.Create();
var messageDigest = sha256.ComputeHash(Encoding.UTF8.GetBytes(message));
using var privateKey = certificate.GetRSAPrivateKey()!;
using var publicKey = certificate.GetRSAPublicKey()!;
var signature = privateKey.SignHash(messageDigest, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
var valid = publicKey.VerifyHash(messageDigest, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
RSA Padding
关于 RSA padding 我没有 research 太多
有 3 种:
PKCS 1 是最开始的 (签名, 加密都可以用)
PSS 是后来用作签名的
OAEP 是后来用作加密的
OpenIddict Core 的 example 是 PKCS 1, 不知道我换掉 ok 不 ok 啦.
关于 PEM, CER, .pem, .cer, .crt .key, .pfx
参考:
网络安全 / crt、pem、pfx、cer、key 作用及区别
那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)
大家都是 X509.
一个 X509 包含证书信息, private key & public key
PEM 和 CER 是 format 格式.
Windows 通常是 CER 格式, Linux 是 PEM.
extension 则非常乱, 通常 Windows 用 .pfx, 里面包含了证书信息, public key 和 private key, 所以要 fully export 需要密码.
Linux 通常会分 2 个文件, 一个负责 public key 和证书信息 .crt, .cer, 另一个负责 private key extension 是 .key
以上全部都是可以相互 convert 的.
ASP.NET Core – Work with X509的更多相关文章
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
- ASP.NET Core 1.1 Preview 1 简介(包含.NETCore 1.1升级公告)
ASP.NET Core 1.1 Preview 1于2016年10月25日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强. 要将现有项目更新到ASP.NET Core 1.1 Pre ...
- ASP.NET Core Kestrel部署HTTPS
ASP.NET Core配置 Kestrel部署HTTPS.现在大部分网站已经部署HTTPS,大家对于安全越来越重视. 今天简单介绍一下ASP.NET Core 部署HTTPS,直接通过配置Kestr ...
- 如何在docker配置asp.net core https协议
本文参考自<Step by step: Expose ASP.NET Core over HTTPS with Docker> 自从微软发布.net core以来,就在许多社区掀起了讨论, ...
- .net core下用HttpClient和asp.net core实现https的双向认证
关于https双向认证的知识可先行google,这时矸接代码. 为了双向认证,我们首先得准备两个crt证书,一个是client.crt,一个是server.crt,有时为了验证是否同一个根证书的验证, ...
- 消除 ASP.NET Core 告警 "No XML encryptor configured. Key may be persisted to storage in unencrypted form"
在 ASP.NET Core 中如果在 DataProtection 中使用了 PersistKeysToFileSystem 或 PersistKeysToFileSystem services.A ...
- ASP.NET Core如何使用WSFederation身份认证集成ADFS
如果要在ASP.NET Core项目中使用WSFederation身份认证,首先需要在项目中引入NuGet包: Microsoft.AspNetCore.Authentication.WsFedera ...
- ASP.NET Core 之 Identity 入门(一)
前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- ASP.NET Core应用的错误处理[3]:ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”
DeveloperExceptionPageMiddleware中间件利用呈现出来的错误页面实现抛出异常和当前请求的详细信息以辅助开发人员更好地进行纠错诊断工作,而ExceptionHandlerMi ...
随机推荐
- Service Mesh Summit 回顾 | 轻舟服务网格的无侵入增强 Istio 经验
在云原生社区近日主办的 Service Mesh Summit 2022 服务网格峰会上,网易数帆云原生技术专家方志恒分享了轻舟服务网格无侵入增强 Istio 的经验,本文据此次分享整理,介绍了对无侵 ...
- 玄机-第一章 应急响应-Linux日志分析
目录 前言 简介 应急开始 准备工作 查看auth.log文件 grep -a 步骤 1 步骤 2 步骤 3 步骤 4 步骤 5 总结 前言 又花了一块rmb玩玄机...啥时候才能5金币拿下一个应急靶 ...
- 【VMware VCF】VMware Cloud Foundation Part 02:部署 Cloud Builder。
VMware Cloud Builder 是用于构建 VMware Cloud Foundation 第一个管理域的自动化部署工具,通过将一个预定义信息的 Excel 参数表导入到 Cloud Bui ...
- Docker 使用Docker创建MySQL容器
使用Docker创建MySQL容器 实践环境 Docker version 20.10.5 MySQL5.7 Centos 7.8 创建步骤 1.拉取MySQL镜像 docker pull mysql ...
- python学习总结(重要!!!)
前取,后不取 index从0开始 list = [1,2,3,4,5,6,7,8,9]print(list[3:7]) #输出:[4, 5, 6, 7]print(list[3:-2]) ...
- 测试工程师-年终总结PPT
2022年年终总结-xxx 一.首页 2022年年终总结暨2023年工作计划 汇报人:测试组-xxx 日期: 2023.1.13 二.目录 1.年度工作概述 2.工作亮点展示 3.持续精进点 4.明年 ...
- 【SpringMVC】02 流程分析
首先是web.xml配置SpringMVC最核心的东西,DispatcherServlet 也称为[请求分发器][前端控制器][分发Servlet] <!--1.注册DispatcherServ ...
- 【SpringBoot】03 自动装配原理探索
SpringBoot的依赖探索 首先是一个父级依赖管理的pom.xml [Ctrl + 左键点击]访问进去之后还有父级的父级 到最后才是我们的真正的顶级父类Pom.xml 我们当前的父级坐标 < ...
- 【Java-GUI】06 绘图 Part2 位图处理
绘画程序案例: 原视频排错找了半天,原来是变量名的问题 package cn.dzz; import java.awt.*; import java.awt.event.*; import java. ...
- 【Tutorial C】05 操作符 & 表达式
基本运算符 C使用运算符(operator)来代表算术运算.例如,+运算符可以使它两侧的值加在一起. 如果您觉得术语"运算符"听起来比较奇怪,那么请您记住那些东西总得有个名称. 与 ...