From 69b3c417f1966ae443cb907d3af5d863b492164a Mon Sep 17 00:00:00 2001 From: duffyduck Date: Fri, 3 Apr 2026 10:02:27 +0200 Subject: [PATCH] Fix cert export: use PFX instead of PEM for .NET Framework compat ExportPkcs8PrivateKey() is only available in .NET Core 3.0+ but Windows PowerShell 5.1 uses .NET Framework 4.x. Switch to PFX export which works on all Windows versions. Co-Authored-By: Claude Opus 4.6 (1M context) --- installer/local-server.js | 14 ++++++++------ installer/setup.ps1 | 28 ++++++++++------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/installer/local-server.js b/installer/local-server.js index 6d95b9d6..47ac7f8d 100644 --- a/installer/local-server.js +++ b/installer/local-server.js @@ -102,18 +102,20 @@ function handleRequest(req, res) { } // Zertifikate laden und HTTPS-Server starten -const certFile = path.join(CERT_DIR, "localhost.crt"); -const keyFile = path.join(CERT_DIR, "localhost.key"); +const pfxFile = path.join(CERT_DIR, "localhost.pfx"); +const pfxPasswordFile = path.join(CERT_DIR, "pfx-password.txt"); -if (!fs.existsSync(certFile) || !fs.existsSync(keyFile)) { +if (!fs.existsSync(pfxFile) || !fs.existsSync(pfxPasswordFile)) { console.error("Zertifikate nicht gefunden in:", CERT_DIR); - console.error("Bitte zuerst setup.ps1 ausführen."); + console.error("Bitte zuerst setup.ps1 ausfuehren."); process.exit(1); } +const pfxPassword = fs.readFileSync(pfxPasswordFile, "utf-8").trim(); + const serverOptions = { - cert: fs.readFileSync(certFile), - key: fs.readFileSync(keyFile), + pfx: fs.readFileSync(pfxFile), + passphrase: pfxPassword, }; const server = https.createServer(serverOptions, handleRequest); diff --git a/installer/setup.ps1 b/installer/setup.ps1 index d7b4c375..8704c3b0 100644 --- a/installer/setup.ps1 +++ b/installer/setup.ps1 @@ -282,28 +282,20 @@ $localhostParams = @{ $localhostCert = New-SelfSignedCertificate @localhostParams Write-Step "Localhost-Zertifikat erstellt: $($localhostCert.Thumbprint)" -# Zertifikat und Key als PEM exportieren (fuer Node.js) +# Zertifikat als PFX exportieren (fuer Node.js) +# PFX funktioniert auf allen Windows-Versionen (.NET Framework + .NET Core) Write-Step "Exportiere Zertifikate fuer den Webserver ..." -# Zertifikat als PEM -$certPem = "-----BEGIN CERTIFICATE-----`n" -$certPem += [Convert]::ToBase64String($localhostCert.RawData, [Base64FormattingOptions]::InsertLineBreaks) -$certPem += "`n-----END CERTIFICATE-----" -Set-Content -Path (Join-Path $certDir "localhost.crt") -Value $certPem -Encoding ASCII +$pfxPassword = [guid]::NewGuid().ToString() +$pfxSecure = ConvertTo-SecureString -String $pfxPassword -Force -AsPlainText +$pfxPath = Join-Path $certDir "localhost.pfx" -# Private Key als PEM -# .PrivateKey ist bei signierten Zertifikaten oft null, daher GetRSAPrivateKey() verwenden -$rsaKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($localhostCert) -if (-not $rsaKey) { - Write-Err "Private Key konnte nicht gelesen werden." - exit 1 -} -$keyBytes = $rsaKey.ExportPkcs8PrivateKey() +Export-PfxCertificate -Cert $localhostCert -FilePath $pfxPath -Password $pfxSecure | Out-Null -$keyPem = "-----BEGIN PRIVATE KEY-----`n" -$keyPem += [Convert]::ToBase64String($keyBytes, [Base64FormattingOptions]::InsertLineBreaks) -$keyPem += "`n-----END PRIVATE KEY-----" -Set-Content -Path (Join-Path $certDir "localhost.key") -Value $keyPem -Encoding ASCII +# Passwort in config speichern (wird vom Server gelesen) +Set-Content -Path (Join-Path $certDir "pfx-password.txt") -Value $pfxPassword -Encoding ASCII + +Write-Step "PFX-Zertifikat exportiert." # CA-Zertifikat exportieren (fuer Deinstallation) $caCertPem = "-----BEGIN CERTIFICATE-----`n"