Generieren von selbstsignierten Zertifikaten mit der .NET-CLI

Es gibt verschiedene Möglichkeiten, selbstsignierte Zertifikate für Entwicklungs- und Testszenarien zu erstellen und zu verwenden. Dieser Artikel behandelt die Verwendung von selbstsignierten Zertifikaten mit dotnet dev-certs und anderen Optionen wie PowerShell und OpenSSL.

Sie können dann mithilfe eines Beispiels überprüfen, ob das Zertifikat geladen wird, z. B. mit einer ASP.NET Core-App, die in einem Container gehostet wird.

Voraussetzungen

Stellen Sie für dotnet dev-certs sicher, dass Sie die richtige Version von .NET installiert haben:

Für dieses Beispiel benötigen Sie den Docker-ClientDocker 17.06 oder höher.

Vorbereiten der Beispiel-App

Verwenden Sie für diese Anleitung eine Beispiel-App, und nehmen Sie wenn nötig Anpassungen vor.

Überprüfen Sie, ob das Dockerfile für die Beispiel-App .NET 8 verwendet.

Je nach Hostbetriebssystem müssen Sie die ASP.NET-Runtime gegebenenfalls aktualisieren. Wenn Sie beispielsweise auf die entsprechende Windows-Runtime abzielen möchten, ändern Sie mcr.microsoft.com/dotnet/aspnet:8.0-nanoservercore-2009 AS runtime in dem Dockerfile in mcr.microsoft.com/dotnet/aspnet:8.0-windowsservercore-ltsc2022 AS runtime.

Dies hilft beispielsweise beim Testen der Zertifikate unter 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"]

Wenn Sie die Zertifikate unter Linux testen, können Sie das vorhandene Dockerfile verwenden.

Stellen Sie sicher, dass die Datei aspnetapp.csproj ein passendes Zielframework enthält:

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

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

</Project>

Hinweis

Wenn Sie dotnet publish-Parameter zum Trimmen der Bereitstellung verwenden möchten, sollten Sie sicherstellen, dass die passenden Abhängigkeiten zur Unterstützung von SSL-Zertifikaten hinzugefügt werden. Aktualisieren Sie die Datei dotnet-docker\samples\aspnetapp\aspnetapp.csproj, um sicherzustellen, dass die richtigen Assemblys zum Container hinzugefügt werden. Informieren Sie sich in diesem Zusammenhang darüber, wie Sie die CSPROJ-Datei so aktualisieren können, dass SSL-Zertifikate unterstützt werden, wenn Sie Trimming für eigenständige Bereitstellungen einsetzen.

Stellen Sie sicher, dass Sie auf die Beispiel-App verweisen.

cd .\dotnet-docker\samples\aspnetapp

Erstellen Sie den Container zum Testen auf lokaler Ebene.

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

Erstellen eines selbstsignierten Zertifikats

Sie können mithilfe der folgenden Tools ein selbstsigniertes Zertifikat erstellen:

Mit dotnet dev-certs

Sie können dotnet dev-certs verwenden, um mit selbstsignierten Zertifikaten zu arbeiten.

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

Hinweis

Der Zertifikatsname, in diesem Fall aspnettapp.pfx, muss mit dem Projektassemblynamen identisch sein. crypticpassword wird als Ersatz für ein Kennwort Ihrer Wahl verwendet. Wenn die Konsole die Meldung "A valid HTTPS certificate is already present" (Es gibt bereit ein gültiges HTTPS-Zertifikat) zurückgibt, gibt es bereits ein vertrauenswürdiges Zertifikat in Ihrem Speicher. Dieses können Sie mithilfe der MMC-Konsole exportieren.

Konfigurieren Sie die Anwendungsgeheimnisse für das Zertifikat:

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

Hinweis

Hinweis: Das Kennwort muss dem Kennwort entsprechen, das für das Zertifikat verwendet wird.

Führen Sie das Containerimage mit einer für HTTPS konfigurierten ASP.NET Core-Instanz aus:

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

Sobald die Anwendung gestartet wurde, navigieren Sie in Ihrem Webbrowser zu https://localhost:8001.

Bereinigung

Wenn die Geheimnisse und Zertifikate nicht verwendet werden, sollten sie unbedingt bereinigt werden.

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

Mit PowerShell

Sie können PowerShell verwenden, um selbstsignierte Zertifikate zu generieren. Dabei hilft Ihnen der PKI-Client.

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

Wenn das Zertifikat generiert wird, sollte es in einem Zertifikatspeicher gespeichert werden, um Tests im Browser durchzuführen.

$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)

An dieser Stellen sollten die Zertifikate über ein MMC-Snap-In abrufbar sein.

Sie können den Beispielcontainer im Windows-Subsystem für Linux (WSL) ausführen:

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

Hinweis

Mit der Volumebereitstellung kann der Dateipfad je nach Host anders aufgebaut sein. Beispielsweise können Sie in WSL /c/certs durch /mnt/c/certs ersetzen.

Wenn Sie den Container verwenden, der zuvor für Windows erstellt wurde, sieht der Ausführungsbefehl wie folgt aus:

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

Navigieren Sie in einem Browser zu „contoso.com:8001“, sobald die Anwendung ausgeführt wird.

Stellen Sie sicher, dass die Hosteinträge aktualisiert werden, damit contoso.com an einer geeigneten IP-Adresse (z. B. 127.0.0.1) antwortet. Wenn das Zertifikat nicht erkannt wird, sollten Sie sich vergewissern, dass das Zertifikat, das mit dem Container geladen wird, ebenfalls vom Host als vertrauenswürdig eingestuft wird, und dass es passende SAN-/DNS-Einträge für contoso.com gibt.

Bereinigung

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

Mit OpenSSL

Sie können OpenSSL verwenden, um selbstsignierte Zertifikate zu erstellen. In diesem Beispiel werden WSL/Ubuntu und eine Bash-Shell mit OpenSSL verwendet.

Dieser Befehl generiert eine .crt- und eine .key-Datei.

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

Wenn Sie eine PFX-Datei erstellen möchten, verwenden Sie den folgenden Befehl:

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

Hinweis

Ab .NET 5 kann Kestrel .crt- und PEM-codierte .key-Dateien zusätzlich zu PFX-Dateien mit einem Kennwort verarbeiten.

Je nach Hostbetriebssystem muss das Zertifikat als vertrauenswürdig eingestuft werden. Auf einem Linux-Host werden Zertifikate auf andere Weise und in Abhängigkeit mit der Distribution als vertrauenswürdig eingestuft.

Für diesen Leitfaden stellen wir das folgende Beispiel für Windows unter Verwendung von PowerShell bereit:

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

Führen Sie das Beispiel mit dem folgenden Befehl in WSL aus:

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

Hinweis

In WSL kann der Pfad der Volumeeinbindung je nach Konfiguration abweichen.

Führen Sie in PowerShell den folgenden Befehl aus:

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

Navigieren Sie in einem Browser zu „contoso.com:8001“, sobald die Anwendung ausgeführt wird.

Stellen Sie sicher, dass die Hosteinträge aktualisiert werden, damit contoso.com an einer geeigneten IP-Adresse (z. B. 127.0.0.1) antwortet. Wenn das Zertifikat nicht erkannt wird, sollten Sie sich vergewissern, dass das Zertifikat, das mit dem Container geladen wird, ebenfalls vom Host als vertrauenswürdig eingestuft wird, und dass es passende SAN-/DNS-Einträge für contoso.com gibt.

Bereinigung

Stellen Sie sicher, dass Sie die selbstsignierten Zertifikate nach Abschluss der Tests löschen.

Get-ChildItem $certKeyPath | Remove-Item

Siehe auch