IdentityServer4: 使用固定证书
IdentityServer4: 使用固定证书
固定证书
本节可基于 IdentityServer4: 配置项持久化 一节的代码基础上进行。
简介
为了保证 IdentityServer4 发布的令牌不被人篡改和伪造,使用签名算法生成的一个签名字符串来保护令牌。IdentityServer4 的签名算法使用 RSA256 加密算法,RSA256 是一个非对称加密算法,用私钥来加密,公钥来解密。私钥必须保证安全性,保存在 IdentityServer4 服务器端,而公钥可以公布出去,公钥是公开的,如果私钥被泄露就很容易被人篡改和伪造令牌。IdentityServer4 为了保护私钥安全,提供了开发环境和生产环境的密钥证书,分别为:
- (1) AddDeveloperSigningCredential:会创建一个临时密钥证书供调试环境用。
- (2) AddSigningCredential:需要指定一个固定的证书,用于生产环境,此时就需要拿到机构颁发的密钥证书,放在 IdentityServer4 服务器上,并在此方法中指定,这样就不会出现临时密钥证书发生变化的情况。
生产环境
生产环境下一般需要使用固定证书签名和验证,以保证在重新启动IdentityServer4 服务器的时候 Token 能验证通过,而不是使用的
临时证书,导致验证失败。
这里,我们使用 OpenSSL 工具来生成一个固定的 RSA256 加密证书,用于生产环境。
注意:RSA256 加密证书的长度要求在 2048 以上。
生成证书
下载 OpenSSL 工具
到 OpenSSL 工具的官方网站上下载,地址如下:
https://slproweb.com/products/Win32OpenSSL.html
点击“Win64OpenSSL_Light-3_0_8”(用户使用的版本)的“EXE”或“MSI”格式的文件下载,这里下载的是“*.msi”格式的安装程序:
Win64OpenSSL_Light-3_0_8.msi,双击进行安装,记住安装路径, 本示例的安装路径为:C:\Program Files\OpenSSL-Win64,记住这个目录,等会会用到。
设置环境变量
在 Windows10 系统中,OpenSSL 工具安装完成之后,需要设置一下环境变量,在“系统变量”文本框中选择“Path”,添加变量:
C:\Program Files\OpenSSL-Win64
生成 KEY
OpenSSL 工具安装完成,会得到一个工具【Win64 OpenSSL Command Prompt】工具,打开它,在命令提示符下输入如下命令生成 KEY:
C:\Users\wei> openssl req -newkey rsa:2048 -nodes -keyout mvcclient.key -x509 -days 365 -out mvcclient.cer
.....+.........+......+......+.+.....+.......+...+.........+..............+++++++++++++++++++*..+.........+.+.....+....+...+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Hongkong
Locality Name (eg, city) []:HK
Organization Name (eg, company) [Internet Widgits Pty Ltd]:KFC
Organizational Unit Name (eg, section) []:KFC-D
Common Name (e.g. server FQDN or YOUR name) []:DEV
Email Address []:keivin@dotnet.com
这些信息可以任意输入,输入完成后,KEY 也就生成了。打开“C:\Users\wei”目录,查看一下生成的 KEY 文件:
mvcclient.key 和 mvcclient.cer
这 2 个文件就是刚才命令生成的。
(1) mvcclient.key:表示私钥文件,要妥善保管。
(2) mvcclient.cer:表示证书文件,包含持有人的信息,持有人的公钥,以及签署者的签名等信息。
当用户安装了证书之后,便意味着信任了此证书,同时拥有了其中的公钥。
本示例生成的公钥和私钥的文件内容如下:
- 公钥:mvcclient.cer
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIUcs/nIjEyzVsMhTYcjW8XsiEDUrQwDQYJKoZIhvcNAQEL
BQAwezELMAkGA1UEBhMCQ04xETAPBgNVBAgMCEhvbmdrb25nMQswCQYDVQQHDAJI
SzEMMAoGA1UECgwDS0ZDMQ4wDAYDVQQLDAVLRkMtRDEMMAoGA1UEAwwDREVWMSAw
HgYJKoZIhvcNAQkBFhFrZWl2aW5AZG90bmV0LmNvbTAeFw0yMzAzMDgxMjU0MDda
Fw0yNDAzMDcxMjU0MDdaMHsxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhIb25na29u
ZzELMAkGA1UEBwwCSEsxDDAKBgNVBAoMA0tGQzEOMAwGA1UECwwFS0ZDLUQxDDAK
BgNVBAMMA0RFVjEgMB4GCSqGSIb3DQEJARYRa2VpdmluQGRvdG5ldC5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCn3FYlgavMkyL9I4kJRnkF22yO
3Eftm5rxVusa6JM9kpFFFRuUrF6q6loDQApfTqtorpaQhiyp+FeLNNtvm4n6vf/k
gmO4rBsTtzvTWLj2b94DIs2ZTuSjD1w0elU4d+Wgbu9rNNZdS60XAcdp0t/3O0Ww
r8Y00YRUTWMbND97Yf81JEmzG+6W8/k67GPFRTqRymaIkhnpfBf5oPHI0fz2z6Yz
5lsIt5SmZmZCu/w17TGimEkLKMmhEoi84/Mekie4Puo4Cao2UKSABDCItHIofYbT
jUPyk30OfaWQwtl83Zi/01fZ+5/6nVVqNIIxJjVGotItFJoFtpHIVjCvk3wvAgMB
AAGjUzBRMB0GA1UdDgQWBBT0O6teRxunyychvP1bbTYDU0SBRzAfBgNVHSMEGDAW
gBT0O6teRxunyychvP1bbTYDU0SBRzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQBnuKRw5Jl0kBT9xhniDu3jLuC49GA6AhPKDopim7pchtCrNUI6
G5NZh01yZ4xX3/hAVqTzbigp2vIRaDW/W7n0v8dlwwXZpIC6Kzq3+2ylFGAhghwi
HJW/efTqod1zjdGUYuyLp3U1qfLtNxIuPdSpy/+QeBA1CjmyR7hnO0xSeDseGFxn
4HxbXfsNVSvu/NK6iwrlo080SEUts4cu08qHeitVuIF6b6t2/m1Sk1GpLKz3tb+N
jRHrf3gOnqQNQWhyzQD3QWjtsd1UhYR7mZUzXIQ27Gq6QpIwen/1fOz9puWkTq2O
wSwV1198ePpA1NijlqlL1Vmoe1ODbmj8377k
-----END CERTIFICATE-----
- 私钥:mvcclient.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCn3FYlgavMkyL9
I4kJRnkF22yO3Eftm5rxVusa6JM9kpFFFRuUrF6q6loDQApfTqtorpaQhiyp+FeL
NNtvm4n6vf/kgmO4rBsTtzvTWLj2b94DIs2ZTuSjD1w0elU4d+Wgbu9rNNZdS60X
Acdp0t/3O0Wwr8Y00YRUTWMbND97Yf81JEmzG+6W8/k67GPFRTqRymaIkhnpfBf5
oPHI0fz2z6Yz5lsIt5SmZmZCu/w17TGimEkLKMmhEoi84/Mekie4Puo4Cao2UKSA
BDCItHIofYbTjUPyk30OfaWQwtl83Zi/01fZ+5/6nVVqNIIxJjVGotItFJoFtpHI
VjCvk3wvAgMBAAECggEATOIFbv5acsO9ldXt0Rq/Gairqy9HnpPTvtBBtLxrnBsC
gHKvhEQCxCO8gJqXZZnBtpuoiJ9724nMhwz5qL/Dzd2yU7ZI+G+To08cjqunY/BO
7n7FTn+tBuZlJAAYAlogCYBmFmNH/8lGiTAeZuDYBgPW4ptPnCeOhZJAX1hp7xdw
fBbnWiQ8R16vsGhuCrfP2XGcN0DT8hBqdm8o9kD0L5ro+wubPky5IFUcUxJPnkIu
R0wIUtt0epJGRjpqi2q99paqKEOzo5QZxkZBhlQck9BogYMC/aBl2Mh4APcnI05k
T1Q5zXTl3tEbtaSZz5eYxukDpA8WWWxfpZx7X1UnMQKBgQDKoFwMqX+RHxv1vpUH
L3z9BInzIpDiMKSmBeRzuFXJ4jUb9bPgnyfv/GNiGiSTERELB0Yzkbi0jYGvKUXQ
UUqXtY2F6ZIOxtJD+06adxdc3k4KTUEJKK6CvTs4Mz7r1mT97SQDqyPWOWqISYD/
yOjZsDMGoW7U1PN7mTfQxJgESQKBgQDUE6G8rLjN19C4o4dZAqiEond885g0XNvO
pk8rtaylbQSPs5qiYLEWnxfhP/ZwG16Uw+nk+UX9xr5ByDcy6ePlLoy2gTrkwtyq
RQkH4GygAajEevEh59N/tcydxyO1ekfKeV6upcIj1cuCFD0JP+nX8idq5DFYH6f/
4dUQVw0MtwKBgH9FMgwR+rpgW+ODDYAx58PUsgExWOd5vjE5ykCVK+1eVBV3wr/3
t9IZKSNZYFevhJD0xLdndCiUKTyoI92w8bVQp8/Q4Zi+cRuaIckLvHTsfQAjfhIO
p24fBa9LIN5pD44fAVv8hsnrzmpEIO6IdxkkfyhPBZpRF44ussxCb2lhAoGACni9
r7dHmMJjR/qrIDYFZCcxhzXv+gXrxJRprFrYH4L2irHvnLzxgZBxeWnTHU38qZPS
5L96OUGq+0yLjTQHULWvtQNEiS8l/jJSc9UdB/mM/8aiSW5M/y1W4SOIG9nh2ZmM
l0sP/vz7g3zEVsSVI1iNobWKyjMl9HiOMLRbrJkCgYEAnGI2DZO7p3+yPf1zIWVg
AL7B7rBQYz7UNYATEYS/6eBbnXFqF7ozBbS5MTALsk3QghF8SexamzBQPJfe3WQv
Yp/0nK8E5MJtVzEi1Xz3EtHyuhEHa3ngPEkc/iAOHCKeA6HtcP/f8zRfPTMfrG3L
s05wTYNm2oDyroJ1ze6QCoI=
-----END PRIVATE KEY-----
合并成.pfx 文件
从上面可以看到公钥和私钥都是可以查看的,很不安全。而 *.pfx
文件可以使用密码保护起来,这样更安全一些,所以,我们要将证书文件和私钥文件合并成一个 *.pfx
文件。
这里使用 OpenSSL 命令合并文件,命令如下:
openssl pkcs12 -export -in mvcclient.cer -inkey mvcclient.key -out mvcclient.pfx
Enter Export Password:123456
Verifying - Enter Export Password:123456
命令执行后,需要输入 2 次密码,输入的密码必须一致,输入时密码不显示,密码要牢记。
完成后,在目录看到的“mvcclient.pfx”文件,这就是合并后的加密证书文件,我们在 IdentityServer4 服务器上就是使用这个证书。
使用证书
配置证书
在 IdentityServer4项目的 appsettings.json 文件中配置证书:
"Certificates": {
"CerPath": "Certificates\\mvcclient.pfx",
"Password": "123456"
}
(1) CerPath 指定证书文件的路径。
(2) Password 指定生成.pfx 证书时输入的密码。需要将.pfx 证书文件放在一个安全的目录中。
加载证书
在 IdentityServer4 项目的 Program 类中将开发环境下的临时证书修改为生产环境下的固定证书:
将如下这一行代码:
ids4Builder.AddDeveloperSigningCredential(); // 开发环境临时证书,重启后失效。
替换为:
//注册IdentityServer
var ids4Builder = builder.Services.AddIdentityServer()...;
//获取证书路径
var path = Path.Combine(Environment.CurrentDirectory, builder.Configuration["Certificates:CerPath"]);
//获取证书密码
var pwd = builder.Configuration["Certificates:Password"];
//生成X509证书
var cert = new X509Certificate2(path, pwd);
//在生产环境下使用固定证书
ids4Builder.AddSigningCredential(cert);
此代码说明如下:
(1). 需要添加 System.Security.Cryptography.X509Certificates 命名空间。
(2). 使用 Environment.CurrentDirectory 获取当前应用程序的工作目录:
如果未发布,则工作目录就是:*\bin\Debug\net6.0
。
如果已发布,则工作目录就是:*\bin\Release\net6.0\publish
, *
是项目的路径。
(3). 使用 Configuration["Certificates:CerPath"]获取 appsettings.json 配置文件中配置的证书路径。
(4). 使用 Configuration["Certificates:Password"]在 appsettings.json 中获取生成证书时的密码。
(5). 使用 new X509Certificate2(path, pwd)根据证书路径和密码生成 X509 证书。
(6). 最后使用 AddSigningCredential(cert)在生产环境下加载固定证书。
在 IdentityServer4 项目根目录添加一个名称为:Certificates 的文件夹,然后将omvcclient.pfx 证书文件复制到此文件夹中.
发布项目的时候要注意,Certificates 不会随发布项目时一起发布,需要单独发布,右击“Certificates”文件夹,选择“发布 Certificates” 即可将该文件夹发布发布目录下。
如果运行发布后的*.exe 文件,则必须单独发布 Certificates 文件夹,否则证书将无法加载。
在生产环境下加载固定证书,使用 IdentityServer4 认证和授权,并访问受保护的 API 资源已经成功实现了,基于此方法,可以在实际项目中使用。
启动 IdentityServer4 项目,此时在生产环境下加载固定证书,使用 IdentityServer4 认证和授权,并访问受保护的 API 资源已经成功实现了,基于此方法,可以在实际项目中使用。
验证 AccessToken
我们可以将得到的token在 https://jwt.io 网站来认证一下:把后缀为 .cer的公钥、key的私钥复制到验证中,看到【Signature Verified】的字样,表明 AccessToken 没有被篡改,如下图所示:
AccessToken
eyJhbGciOiJSUzI1NiIsImtpZCI6IjQzMjE3QzNGNzY1MEVGRUIyNTU4RTNERjc2REY4QzJDRTVEQ0ZDNkFSUzI1NiIsInR5cCI6ImF0K2p3dCIsIng1dCI6IlF5RjhQM1pRNy1zbFdPUGZkdC1NTE9YY19HbyJ9.eyJuYmYiOjE2NzgyODE0NDUsImV4cCI6MTY3ODI4NTA0NSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NjAwMSIsImNsaWVudF9pZCI6Ik12Y0FwcCIsInN1YiI6IjAwMDAxIiwiYXV0aF90aW1lIjoxNjc4MjgxNDQyLCJpZHAiOiJsb2NhbCIsImp0aSI6IjQ3MkZFN0JEMzZGMjE0MjJBQTU5MTQyQzY2NjI4RjgzIiwic2lkIjoiOTAzOENDNEZBN0IxNkE2NUNCNTZEMDg5Q0RDM0MwMzgiLCJpYXQiOjE2NzgyODE0NDUsInNjb3BlIjpbIm9wZW5pZCIsInByb2ZpbGUiLCJPQUFQSSIsIm9mZmxpbmVfYWNjZXNzIl0sImFtciI6WyJwd2QiXX0.Pq6Jr1t9U0kbqOKRfBokuLud0G8r7b39gtxrpSjDdZJk2JP79s48OpBGC7T11SGyAAO3Y54-PwZZdsKu72XFnu1he7YeEdTPYNpx-WUK_3oyiZHbB75tLGAeiTHLsr3m1mO8Q-oKQjPgXDxZ13qEfQBeaXhNbQw4_pPwEu80e_gkURkgeN1Tlq0EeqZTs7MF8dluLiiYFfd5Lk71htUjevWtuv9ASUf6vO3MBL5WlWNqGvcAtjgMLBe5P0sqnI_ZTue7gpLPbCvJ8ybAuYIAnIxw6i7kwkCktrHpHu33jHqH5vK8aDev16THtJVOyaIBzoc1lqZY3DMhr81Y5Y1LlQ
posted on 2023-11-21 17:17 一只小青蛙-呱-呱-dyj 阅读(149) 评论(0) 编辑 收藏 举报