自学内容网 自学内容网

NET8部署Kestrel服务HTTPS深入解读TLS协议之Certificate证书

Certificate证书

Certificate称为数字证书。数字证书是一种证明身份的电子凭证,它包含一个公钥和一些身份信息,用于验证数字签名和加密通信。数字证书在网络通信、电子签名、认证授权等场景中都有广泛应用。其特征如下:

  • 由权威机构颁发,人们可以在互联网上用来识别对方的身份。
  • 证书遵循国际标准 ITUTX.509,主要包括下面的内容:
    • 版本信息
    • 序列号,每个证书都有唯一的序列号
    • 使用的签名算法
    • 签发机构(命名规则一般采用 X.500格式)
    • 有效期
    • 证书所有人的名称
    • 证书所有人的公钥 public key
    • 证书发行者的签名

证书等级

  • Root Cartificate:根证书

根证书:签名(Root CA's signature)是用根私钥(Root CA's private key)签的。所以验证根证书签名(Root CA's signature)要用根公钥(Root CA's public key)才能验证通过。这种情况称为自签名(self-sign)。

  • Intermediate Cartificate:中间证书

中介证书是被根证书签名的证书,是被根证书的私钥进行签名的,因此要验证中介证书也需要使用根公钥。

  • End-entity Certificate:终端实体证书

终端实体证书是有中介证书签发的;使用中介证书对终端实体进行认证的目的是为了减少根证书签名的负担,相当于使用一个中介来代替根实行认证的权利。

证书链

在RFC5280中,证书链或信任链被定义为“证书路径”。换句话说,信任链是指您的SSL证书以及它如何链接回受信任的证书颁发机构。为了使SSL证书可信,它必须可以追溯到它被签署的信任根,这意味着链中的所有证书——终端实体证书、中间证书和根证书,都需要得到适当的信任。信任链分为三个部分:

Windows证书管理

通过Win+R运行:mmc确定,文件->添加/删除管理单元,进行配置证书管理。

证书工具

证书的管理工具有很多,下面列举几种常用的工具:

  • PowerShell CLI:New-SelfSignedCertificate
  • CMD CLI:Certutil
  • X Certificate and Key management
  • CMD CLI:OpenSSL
  • JDK CTL:keytool

New-SelfSignedCertificate

在Windows中,通过PowerShell CLI:New-SelfSignedCertificate进行创建自定义签名证书。说实话,笔者翻烂了官方文档对该工具使用介绍挺粗糙的,一堆的坑准备好踩吧。

1、创建X509证书链

# PowerShell环境(以管理员身份运行)

# 默认存储位置:cert:LocalMachine\My【本地计算机\个人】
#准备条件
$pfxPassword = ConvertTo-SecureString -String "[pfx加密]" -Force -AsPlainText
$pfxFilePath = "[pfx文件路径]"
$cerFilePath = "[cer文件路径]"

# 语法结构
New-SelfSignedCertificate `
-Subject [颁发给] `
-DnsName [使用者可选名称(Web域名)] `
-NotAfter (Get-Date).AddYears(20) `
-CertStoreLocation "cert:LocalMachine\My" `
-FriendlyName "[友好名称]" `
-HashAlgorithm SHA256 `
-KeyUsageProperty All `
-KeyUsage CertSign, CRLSign, DigitalSignature
-TextExtension @("2.5.29.19={text}CA=1&pathlength=1")

# 可缺省-Subject参数时,生成证书时默认取DnsName信息为[颁发给]者。
# 可缺省 -KeyAlgorithm和-KeyLength参数时,默认为RSA 2048。
# 可缺省 -NotBefore参数时,默认为从系统当前时间起始。
# 可缺省 -NotAfter参数时,生成证书时默认有效期为1年。
# 可缺省-FriendlyName参数时,生成证书时[友好名称]为空。
# 可缺省 -HashAlgorithm参数时,默认值SHA256。
# 可缺省 -KeyUsageProperty参数,指定私钥的键用法属性的键用法。默认值None。(使用底层KSP的默认值)

# 必须 -KeyUsage参数[密钥用法],指定在证书的密钥使用扩展名中设置的密钥用法。可接受的参数项:
# CertSign:证书签名
# CRLSign:CRL签名
# DataEncipherment:数据加密
# DecipherOnly
# DigitalSignature:数字签名
# EncipherOnly
# KeyAgreement
# KeyEncipherment:钥匙加密
# None:缺省时无
# NonRepudiation

# 必须 -TextExtension参数[目的用途],指定证书扩展数组为字符串,每个字符串必须采用OID对象标识符。
# 所有颁发的策略 (2.5.29.32.0)
# 客户端身份验证 (1.3.6.1.5.5.7.3.2)
# 服务器身份验证 (1.3.6.1.5.5.7.3.1)
# BitLocker驱动器加密 (1.3.6.1.4.1.311.67.1.1)
# 加密文档系统 (1.3.6.1.4.1.311.10.3.4)
# 文档签名 (1.3.6.1.4.1.311.10.3.12)
# 安全电子邮件 (1.3.6.1.5.5.7.3.4)
# 语法: TextExtension @(2.5.29.37={text}{oid},{oid})
# Example: TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
(1) Root根证书

根证书完全不需要-Subject [颁发给]和-DnsName [使用者可选名称(Web域名)],只需要起个友好名称做为颁发者,示例如下:

# Root certificate generation
 New-SelfSignedCertificate `
-Subject "Kingser RSA Root Certificate Authority 2022" `
-NotAfter (Get-Date).AddYears(30) `
-CertStoreLocation "cert:LocalMachine\My" `
-FriendlyName "Kingser RSA Root Certificate Authority 2022" `
-KeyUsageProperty All `
-KeyUsage CertSign, CRLSign, DigitalSignature `
-TextExtension @("2.5.29.19={text}CA=1&pathlength=1")

# Gets certificate generation the path
$certificatePath = ( Get-ChildItem -Path cert:\LocalMachine\My\"[指纹码]" )

# create temporary certificate path
$tmpPath = "E:\Certificate"
If(!(test-path $tmpPath))
{
New-Item -ItemType Directory -Force -Path $tmpPath
}

# set certificate password here
$pfxPassword = ConvertTo-SecureString -String "[pfx加密]" -Force -AsPlainText
$pfxFilePath = "E:\Certificate\rootCert.pfx"
$cerFilePath = "E:\Certificate\rootCert.cer"

具体实操如下 

 这里有几个坑,需要特别说明一下:

a. # Root certificate generation部分

由于证书生成时,一般默认会指定存放在:cert:LocalMachine\My或cert:CurrentUser\My处。

当执行成功时,系统自动会产生证书的Thumbprint指纹码(如上图)。同时,系统在My和CA两处都会产生该证书,也就是个人证书和中间证书两处入口。不过经检查发现,它指向的仍是同一证书(指纹码相同),但唯独Root根证书不会产生,这是什么原因呢?

经笔者反复测试后,在My和CA两处入口时,它的下级证书创建时才能成功,不然会提示找不到父级证书,导致失败:

 换句话说,-Signer参数似乎只能参照My或CA处的证书,Root受信任区的不能直接拿来生成证书链的子证书。此处微软文档翻烂了笔者都没找到相关资料,巨坑。

b. # Gets certificate generation the path部分

$rootCertPath通过Get-ChildItem -Path cert:\LocalMachine\XX的证书对象,当我把证书注册到Root信任区就无法调用,不可用。

那它为啥会在My和CA两处入口都引用该证书呢?其实笔者也没敢说整明白了。只能从经验上判断当生成证书为子证书时,系统逻辑有可能优先判断该证书是哪个入口开始检索。比如中间证书,所参照父级证书位置当优先从C入口开始检查是否有,没有的话再检索My入口处。不一定正确仅供参考。

c. # create temporary certificate path部分

导出时,可设定一个临时存储证书路径(可选)。当配置了该存放路径时,导出文件变量可以这样:

$pfxFilePath = $tmpPath +"\rootCert.pfx"
$cerFilePath = $tmpPath +"\rootCert.cer"
(2) CA中间证书

中间证书的生成,关键性参数是-Signer参照父级证书,可以设定DnsName域名:

# Gets certificate generation the path
$parentCertPath =( Get-ChildItem -Path cert:\LocalMachine\My\"[指纹码]")

# Intermediate certificate generation
New-SelfSignedCertificate `
-Subject [颁发给] `
-DnsName [域名] `
-Signer $parentCertPath `
-NotAfter (Get-Date).AddYears(20) `
-CertStoreLocation "cert:LocalMachine\My" `
-FriendlyName "[友好名称]" `
-KeyUsageProperty All `
-KeyUsage CertSign, CRLSign, DigitalSignature `
-TextExtension @("2.5.29.19={text}CA=1&pathlength=1")

# set certificate password here
$intermediateCer =( Get-ChildItem -Path cert:\LocalMachine\My\"[指纹码]")
$pfxFilePath = "E:\Certificate\intermediateCert.pfx"
$cerFilePath = "E:\Certificate\intermediateCert.cer"

# Export PfxCertificate the file
$intermediateCer | Export-PfxCertificate -FilePath $pfxFilePath -Password $pfxPassword
# Export Certificate the file
$intermediateCer | Export-Certificate -FilePath $cerFilePath

当然需要注意,-NotAfter参数到期时间,肯定是小于根证书年限的。 具体实操如下 

(3) My终端实体证书

终端证书的生成,同样关键性参数是-Signer参照父级证书,设定DnsName域名基本和中间证书相似。唯一不同的则是-TextExtension参数[目的用途]。比如双向验证时,客户端证书则是提交服务器身份验证,服务端提交客户端身份验证则称之为双向。单向验证仅需要客户端提交服务器身份验证就可以。

它还可以用文件存储系统加密验证,驱动程序签名验证以及文档签名验证等。

# Gets certificate generation the path
$intermediateCer =( Get-ChildItem -Path cert:\LocalMachine\My\"[指纹码]")

# End-Entity certificate generation
New-SelfSignedCertificate `
-Subject [颁发给] `
-DnsName [二级域名] `
-Signer $intermediateCer `
-NotAfter (Get-Date).AddYears(3) `
-CertStoreLocation "cert:LocalMachine\My" `
-FriendlyName "[友好名称]" `
-KeyUsageProperty All `
-KeyUsage DigitalSignature, KeyEncipherment, DataEncipherment `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")

# set certificate password here
$clientCer =( Get-ChildItem -Path cert:\LocalMachine\My\"[指纹码]")
$pfxFilePath = "E:\Certificate\clientCert.pfx"
$cerFilePath = "E:\Certificate\clientCert.cer"

# Export PfxCertificate the file
$clientCer | Export-PfxCertificate -FilePath $pfxFilePath -Password $pfxPassword
# Export Certificate the file
$clientCer | Export-Certificate -FilePath $cerFilePath

具体实操如下 

 此处,仍可再单独配置[客户端身份验证]证书,以备服务器部署验证来源客户端身份。在此就不展开详述,感兴趣的朋友可自行适应创建。

 2、证书部署及管理

#准备条件
$cerFilePath = "E:\Certificate\rootCert.cer"

# 导入Root根证书
Import-Certificate -FilePath $cerFilePath -CertStoreLocation Cert:\LocalMachine\Root
# Cert:\LocalMachine\Root是本地计算机根
# Cert:\CurrentUser\Root是当前用户根

# 检查并移除重复引用的证书
# 检查cert:\LocalMachine\My的重复的Root和CA证书,并移除

# 先检查出要移除的证书指纹码,然后通过Remove-Item进行移除。Remove-Item 参数-DeleteKey为连同私钥一并移除(慎用)
Get-ChildItem -Path cert:\LocalMachine\My
Remove-Item -Path cert:\LocalMachine\My\[指纹码]

# 可以通过检索DnsName值,进行移除
Get-ChildItem -Path cert:\LocalMachine\My -DnsName *xxx* | Remove-Item

 3、Certutil CLI工具

Certutil 是 Windows 操作系统上预装的工具,可用于 校验文件MD5、SHA1、SHA256,下载恶意文件和免杀。它是一个 CLI 程序,可用于转储和显示证书颁发机构(CA),配置信息,证书服务, CA 组件的备份和还原以及验证证书、密钥对和证书链,它作为证书服务的一部分安装。

实际上,Certutil用途非常广泛,它即可以作为渗透测试工具,也可以作为Windows证书管理的运维工具。

Certutil的主要功能包括查看证书、导出证书、导入证书、验证证书链、生成密钥对等。它通常被系统管理员和安全专家用于管理和维护证书、密钥和证书颁发机构(CA)相关的任务。

Certutil命令的设计旨在提供一种灵活而强大的方式来处理数字证书和密钥,以确保系统的安全性和可信度。

可在命令提示符下输入"certutil /?"来查看完整的命令参数列表和使用说明。

具体详解,请见微软官方文档

# 检查证书存储,列出本地计算机或用户的证书存储中的证书
certutil -v -store my
certutil -v -store -user my

# 从文件查看证书详细内容
certUtil -v -dump rootCert.cer

 Certificate and Key management

XCA是一个用于管理非对称密钥(如RSA或DSA)的接口。它被用作创建和签署证书的小型CA。它使用OpenSSL库进行加密操作。

开源地址:GitHub - chris2511/xca: X Certificate and Key management,官方安装包:Download

注意它可以直接通过Microsoft Store微软商店进行安装,也可以手动下载MSI包来使用。

最新版本为xca-2.6.0-win64.msi

1、新建数据库

新使用该工具时,需要新建一个xdb(XCA Database)数据库用来存储证书信息,需要设置一个数据库密码。

2、X509证书构造

序号属性名属性学名

Windows

表示

XCA

表示

描述说明
1Id序列号--
2country Name国家代码--
3stateOrProvince Name州或省名--
4locality Name地方名--
5organization Name组织名--
6organizationUnit Name单位名--
7common Name通用名(*)

颁发者

使用者

内部名称
8email Address邮件地址--
9-签名状态UnusedBits
10-私钥(*)HashAlgorithmRSA 2048
11-

有效期

从...到

NotBefore

NotAfter

12-指纹Thumbprint

[待续]

 参考文档


原文地址:https://blog.csdn.net/morliz/article/details/140625304

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!