Membuat sertifikat yang ditandatangani sendiri dengan .NET CLI

Ada berbagai cara untuk membuat dan menggunakan sertifikat yang ditandatangani sendiri untuk skenario pengembangan dan pengujian. Artikel ini membahas penggunaan sertifikat yang ditandatangani sendiri dengan dotnet dev-certs, dan opsi lain seperti PowerShell dan OpenSSL.

Anda kemudian dapat memvalidasi bahwa sertifikat dimuat menggunakan contoh seperti aplikasi ASP.NET Core yang dihosting dalam kontainer.

Prasyarat

Untuk dotnet dev-certs, pastikan untuk menginstal versi .NET yang sesuai:

Sampel ini memerlukan klien Docker.

Menyiapkan aplikasi sampel

Untuk panduan ini, Anda akan menggunakan aplikasi sampel dan membuat perubahan jika sesuai.

Periksa apakah aplikasi sampel Dockerfile menggunakan .NET 10.

Bergantung pada OS host, Anda mungkin perlu memperbarui runtime ASP.NET. Misalnya, untuk menargetkan runtime Windows yang sesuai, ubah mcr.microsoft.com/dotnet/aspnet:10.0-nanoservercore-2009 AS runtime ke mcr.microsoft.com/dotnet/aspnet:10.0-windowsservercore-ltsc2022 AS runtime di Dockerfile.

Misalnya, ini akan membantu menguji sertifikat di Windows:

# https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md
FROM mcr.microsoft.com/dotnet/sdk:10.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:10.0-windowsservercore-ltsc2022 AS runtime
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["aspnetapp"]

Jika Anda menguji sertifikat di Linux, Anda dapat menggunakan Dockerfile yang ada.

Pastikan aspnetapp.csproj menyertakan kerangka kerja target yang sesuai:

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

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

</Project>

Nota

Jika Anda ingin menggunakan dotnet publish parameter untuk memangkas penyebaran, pastikan dependensi yang sesuai disertakan untuk mendukung sertifikat SSL. Perbarui file dotnet-docker\samples\aspnetapp\aspnetapp.csproj untuk memastikan bahwa rakitan yang sesuai disertakan dalam kontainer. Sebagai referensi, periksa cara memperbarui file .csproj untuk mendukung sertifikat SSL saat menggunakan pemangkasan untuk penyebaran mandiri.

Pastikan Anda menunjuk ke aplikasi sampel.

cd .\dotnet-docker\samples\aspnetapp

Buat kontainer untuk pengujian secara lokal.

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

Membuat sertifikat yang ditandatangani sendiri

Anda dapat membuat sertifikat yang ditandatangani sendiri:

Dengan dotnet dev-certs

Anda dapat menggunakan dotnet dev-certs untuk bekerja dengan sertifikat yang ditandatangani sendiri.

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

Nota

Nama sertifikat, dalam hal ini aspnetapp.pfx, harus cocok dengan nama rakitan proyek. $CREDENTIAL_PLACEHOLDER$ mewakili kata sandi yang Anda pilih sendiri. Jika konsol mengembalikan "Sertifikat HTTPS yang valid sudah ada.", sertifikat tepercaya sudah ada di penyimpanan Anda. Anda dapat mengekspornya menggunakan Konsol MMC.

Dalam .NET 10 dan yang lebih baru, jika Anda menjalankan dotnet dev-certs https --trust di dalam instans Subsistem Windows untuk Linux (WSL), perintah juga mempercayai sertifikat pada host Windows.

Dalam .NET 10 dan yang lebih baru, sertifikat yang dihasilkan mencakup nama alternatif subjek (SS) untuk host.docker.internal dan host.containers.internal, yang memungkinkan Anda menggunakan sertifikat langsung dalam skenario pengembangan lokal berbasis kontainer tanpa konfigurasi tambahan.

Untuk memverifikasi bahwa sertifikat pengembangan tepercaya ada, jalankan dotnet dev-certs https --check --trust.

Konfigurasikan rahasia aplikasi, untuk sertifikat:

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

Nota

Kata sandi harus cocok dengan kata sandi yang digunakan untuk sertifikat.

Jalankan gambar kontainer dengan ASP.NET Core yang dikonfigurasi untuk HTTPS:

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

Setelah aplikasi dimulai, navigasikan ke https://localhost:8001 di browser web Anda.

Pembersihan

Jika rahasia dan sertifikat tidak digunakan, pastikan untuk membersihkannya.

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

Dengan PowerShell

Anda dapat menggunakan PowerShell untuk membuat sertifikat yang ditandatangani sendiri. Klien PKI dapat digunakan untuk menghasilkan sertifikat yang ditandatangani sendiri.

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

Sertifikat akan dibuat, tetapi untuk tujuan pengujian, harus ditempatkan di toko sertifikasi untuk pengujian di browser.

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

Pada titik ini, sertifikat harus dapat dilihat dari snap-in MMC.

Anda dapat menjalankan kontainer sampel di Subsistem Windows untuk Linux (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="$CREDENTIAL_PLACEHOLDER$" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/contoso.com.pfx -v /c/certs:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp

Nota

Dengan mount volume, path file dapat ditangani secara berbeda bergantung pada host. Misalnya, di WSL Anda dapat mengganti /c/certs dengan /mnt/c/certs.

Jika Anda menggunakan kontainer yang dibuat sebelumnya untuk Windows, perintah jalankan akan terlihat seperti berikut ini:

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="$CREDENTIAL_PLACEHOLDER$" -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\contoso.com.pfx -v c:\certs:C:\https aspnetapp:my-sample

Setelah aplikasi aktif, navigasikan ke contoso.com:8001 di browser.

Pastikan bahwa entri host diperbarui agar contoso.com merespon pada alamat IP yang sesuai (misalnya 127.0.0.1). Jika sertifikat tidak dikenali, pastikan bahwa sertifikat yang dimuat dengan kontainer juga dipercaya pada host, dan bahwa ada entri SAN / DNS yang sesuai untuk contoso.com.

Pembersihan

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

Dengan OpenSSL

Anda dapat menggunakan OpenSSL untuk membuat sertifikat yang ditandatangani sendiri. Contoh ini menggunakan WSL / Ubuntu dan shell bash dengan OpenSSL.

Perintah ini menghasilkan .crt dan .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

Untuk mendapatkan .pfx, gunakan perintah berikut:

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

Nota

Mulai dari .NET 5, Kestrel dapat mengambil file .crt dan file .key yang dikodekan dalam format PEM, selain file .pfx dengan kata sandi.

Tergantung pada OS host, sertifikat perlu dipercaya. Pada host Linux, 'mempercayai' sertifikat berbeda dan bergantung pada distro.

Untuk tujuan panduan ini, berikut adalah contoh di Windows menggunakan PowerShell:

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

Jalankan sampel menggunakan perintah berikut di 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

Nota

Di WSL, jalur pemasangan volume mungkin berubah tergantung pada konfigurasi.

Jalankan perintah berikut di 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

Setelah aplikasi aktif, navigasikan ke contoso.com:8001 di browser.

Pastikan bahwa entri host diperbarui agar contoso.com merespon pada alamat IP yang sesuai (misalnya 127.0.0.1). Jika sertifikat tidak dikenali, pastikan bahwa sertifikat yang dimuat dengan kontainer juga dipercaya pada host, dan bahwa ada entri SAN / DNS yang sesuai untuk contoso.com.

Pembersihan

Pastikan untuk membersihkan sertifikat yang ditandatangani sendiri setelah dilakukan pengujian.

Get-ChildItem $certKeyPath | Remove-Item

Lihat juga