使用 .NET CLI 生成自签名证书

有多种方法可用于开发和测试方案创建和使用自签名证书。 本文介绍了如何将自签名证书与 dotnet dev-certs 结合使用,以及其他选项,如 PowerShellOpenSSL

然后,可以使用容器中托管 的 ASP.NET Core 应用 等示例来验证证书是否加载。

先决条件

对于 dotnet dev-certs,请务必安装适当的 .NET 版本:

此示例需要 Docker 17.06 或更高版本的 Docker 客户端

准备示例应用

对于本指南,你将使用 示例应用 并在适当情况下进行更改。

检查示例应用 Dockerfile 是否正在使用 .NET 8。

可能需要更新 ASP.NET 运行时,具体取决于主机 OS。 例如,若要以适当的 Windows 运行时为目标,请在 Dockerfile 中将 mcr.microsoft.com/dotnet/aspnet:8.0-nanoservercore-2009 AS runtime 更改为 mcr.microsoft.com/dotnet/aspnet:8.0-windowsservercore-ltsc2022 AS runtime

例如,这有助于在 Windows 上测试证书:

# https://hub.docker.com/_/microsoft-dotnet
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /source

# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore -r win-x64

# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /source/aspnetapp
RUN dotnet publish -c release -o /app -r win-x64 --self-contained false --no-restore

# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:8.0-windowsservercore-ltsc2022 AS runtime
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["aspnetapp"]

如果要在 Linux 上测试证书,可以使用现有的 Dockerfile。

确保 aspnetapp.csproj 包括相应的目标框架:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <!--Other Properties-->
  </PropertyGroup>

</Project>

注释

如果要使用 dotnet publish 参数对部署进行裁剪,请确保包含适当的依赖项以支持 SSL 证书。 更新 dotnet-docker\samples\aspnetapp\aspnetapp.csproj 文件,以确保容器中包含相应的程序集。 有关参考,请查看如何更新 .csproj 文件以便在对自包含部署应用剪裁时支持 SSL 证书

确保指向示例应用。

cd .\dotnet-docker\samples\aspnetapp

在本地生成用于测试的容器。

docker build -t aspnetapp:my-sample -f Dockerfile .

创建自签名证书

可以创建自签名证书:

使用 dotnet dev-certs

您可以使用 dotnet dev-certs 来处理自签名证书。

dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
dotnet dev-certs https --trust

注释

在这种情况下,证书名称 aspnetapp.pfx 必须与项目程序集名称匹配。 crypticpassword 用作占位符,以替代您自己选择的密码。 如果控制台返回“已存在有效的 HTTPS 证书”,则说明您的存储中已存在受信任的证书。 可以使用 MMC 控制台导出它。

为证书配置应用程序机密:

dotnet user-secrets -p aspnetapp\aspnetapp.csproj init
dotnet user-secrets -p aspnetapp\aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "crypticpassword"

注释

注意:密码必须与用于证书的密码匹配。

使用为 HTTPS 配置的 ASP.NET Core 运行容器映像:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -v $env:APPDATA\microsoft\UserSecrets\:C:\Users\ContainerUser\AppData\Roaming\microsoft\UserSecrets -v $env:USERPROFILE\.aspnet\https:C:\Users\ContainerUser\AppData\Roaming\ASP.NET\Https mcr.microsoft.com/dotnet/samples:aspnetapp

应用程序启动后,在 Web 浏览器中导航到 https://localhost:8001

清除

如果机密和证书未使用,请确保清理它们。

dotnet user-secrets remove "Kestrel:Certificates:Development:Password" -p aspnetapp\aspnetapp.csproj
dotnet dev-certs https --clean

使用 PowerShell

可以使用 PowerShell 生成自签名证书。 PKI 客户端可用于生成自签名证书。

$cert = New-SelfSignedCertificate -DnsName @("contoso.com", "www.contoso.com") -CertStoreLocation "cert:\LocalMachine\My"

将生成证书,但出于测试目的,应放置在证书存储中,以便在浏览器中进行测试。

$certKeyPath = "c:\certs\contoso.com.pfx"
$password = ConvertTo-SecureString 'password' -AsPlainText -Force
$cert | Export-PfxCertificate -FilePath $certKeyPath -Password $password
$rootCert = $(Import-PfxCertificate -FilePath $certKeyPath -CertStoreLocation 'Cert:\LocalMachine\Root' -Password $password)

此时,应该可以从 MMC 管理单元查看证书。

可以在适用于 Linux 的 Windows 子系统中运行示例容器(WSL):

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/contoso.com.pfx -v /c/certs:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp

注释

请注意,装载卷后,根据主机的不同,文件路径的处理方式可能有所不同。 例如,在 WSL 中,可以将 /c/certs 替换为 /mnt/c/certs

如果使用的是之前为 Windows 生成的容器,则运行命令将如下所示:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\contoso.com.pfx -v c:\certs:C:\https aspnetapp:my-sample

应用程序启动后,在浏览器中导航到 contoso.com:8001。

请确保主机条目已更新,以便 contoso.com 针对相应的 IP 地址进行应答(例如 127.0.0.1)。 如果无法识别证书,请确保随容器一起加载的证书在主机上也受信任,并确保存在 contoso.com 的适当 SAN/DNS 条目。

清除

$cert | Remove-Item
Get-ChildItem $certKeyPath | Remove-Item
$rootCert | Remove-item

使用 OpenSSL

可以使用 OpenSSL 创建自签名证书。 此示例使用 WSL/Ubuntu 和 bash shell,并使用 OpenSSL

此命令生成 .crt 和 .key。

PARENT="contoso.com"
openssl req \
-x509 \
-newkey rsa:4096 \
-sha256 \
-days 365 \
-nodes \
-keyout $PARENT.key \
-out $PARENT.crt \
-subj "/CN=${PARENT}" \
-extensions v3_ca \
-extensions v3_req \
-config <( \
  echo '[req]'; \
  echo 'default_bits= 4096'; \
  echo 'distinguished_name=req'; \
  echo 'x509_extension = v3_ca'; \
  echo 'req_extensions = v3_req'; \
  echo '[v3_req]'; \
  echo 'basicConstraints = CA:FALSE'; \
  echo 'keyUsage = nonRepudiation, digitalSignature, keyEncipherment'; \
  echo 'subjectAltName = @alt_names'; \
  echo '[ alt_names ]'; \
  echo "DNS.1 = www.${PARENT}"; \
  echo "DNS.2 = ${PARENT}"; \
  echo '[ v3_ca ]'; \
  echo 'subjectKeyIdentifier=hash'; \
  echo 'authorityKeyIdentifier=keyid:always,issuer'; \
  echo 'basicConstraints = critical, CA:TRUE, pathlen:0'; \
  echo 'keyUsage = critical, cRLSign, keyCertSign'; \
  echo 'extendedKeyUsage = serverAuth, clientAuth')

openssl x509 -noout -text -in $PARENT.crt

若要获取 .pfx,请使用以下命令:

openssl pkcs12 -export -out $PARENT.pfx -inkey $PARENT.key -in $PARENT.crt

注释

从 .NET 5 开始,Kestrel 除了支持具有密码的 .pfx 文件外,还可以接受 .crt 文件和 PEM 编码的 .key 文件。

根据主机 OS,证书需要受信任。 在 Linux 主机上,证书“信任”不同,并且依赖于发行版。

出于本指南的目的,下面是使用 PowerShell 的 Windows 中的一个示例:

Import-Certificate -FilePath $certKeyPath -CertStoreLocation 'Cert:\LocalMachine\Root'

在 WSL 中使用以下命令运行示例:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/contoso.com.crt -e ASPNETCORE_Kestrel__Certificates__Default__KeyPath=/https/contoso.com.key -v /c/path/to/certs:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp

注释

在 WSL 中,卷装载路径可能会根据配置而发生变化。

在 PowerShell 中运行以下命令:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\contoso.com.crt -e ASPNETCORE_Kestrel__Certificates__Default__KeyPath=c:\https\contoso.com.key -v c:\certs:C:\https aspnetapp:my-sample

应用程序启动后,在浏览器中导航到 contoso.com:8001。

请确保主机条目已更新,以便 contoso.com 针对相应的 IP 地址进行应答(例如 127.0.0.1)。 如果无法识别证书,请确保随容器一起加载的证书在主机上也受信任,并确保存在 contoso.com 的适当 SAN/DNS 条目。

清除

完成测试后,请务必清理自签名证书。

Get-ChildItem $certKeyPath | Remove-Item

另请参阅