Created
June 23, 2022 16:46
-
-
Save magnuswatn/f53ebf304f877850f2a362361d5e279c to your computer and use it in GitHub Desktop.
New-CSR.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.Synopsis | |
Script som genererer en CSR for et SSL/TLS-sertifikat. | |
.DESCRIPTION | |
Scriptet genererer en nøkkel og CSR på lokal maskin, for innsendelse til en CA. | |
Som standard vil det genereres en RSA-nøkkel (2048 bits) som vil være eksporterbar | |
og legges i LocalMachine-storen, men dette kan endres med -ECDSA, -CurrentUser og -NotExportable. | |
Vær obs på at nøkkelen blir en såkalt "CNG-nøkkel", så noe eldre programvare kan | |
få problemer med dette. Men det er på tide å støtte det nå altså. | |
.NOTES | |
Author : Magnus Watn | |
#> | |
using namespace System.Security.Cryptography | |
param( | |
[String[]]$dnsNames, | |
[System.Net.Dns[]]$ipAddresses, | |
[switch] $ECDSA, | |
[switch] $CurrentUser, | |
[switch] $NotExportable, | |
[switch] $NoSubject | |
) | |
$ErrorActionPreference = "Stop" | |
if ($dnsNames.Length -gt 0) { | |
[string]$DistinguishedName = "CN=$($dnsNames[0])" | |
} | |
elseif ($ipAddresses.Length -gt 0) { | |
[string]$DistinguishedName = "CN=$($ipAddresses[0])" | |
} | |
else { | |
throw New-Object System.ArgumentException "Either -dnsNames or -ipAdresses must be specified" | |
} | |
if ($NoSubject) { | |
[string]$DistinguishedName = $null | |
} | |
$keyCreationParamters = [CngKeyCreationParameters]::new() | |
if (!$CurrentUser) { | |
$keyCreationParamters.KeyCreationOptions = [CngKeyCreationOptions]::MachineKey | |
} | |
if (!$NotExportable) { | |
$keyCreationParamters.ExportPolicy = [CngExportPolicies]::AllowExport | |
} | |
try { | |
if ($ECDSA) { | |
$key = [CngKey]::create( | |
[CngAlgorithm]::ECDsaP256, | |
[Guid]::NewGuid().toString(), | |
$keyCreationParamters | |
) | |
} | |
else { | |
$keyCreationParamters.Parameters.Add( | |
[CngProperty]::new( | |
"Length", | |
[System.BitConverter]::GetBytes(2048), | |
[CngPropertyOptions]::None | |
) | |
) | |
$key = [CngKey]::create( | |
[CngAlgorithm]::Rsa, | |
[Guid]::NewGuid().toString(), | |
$keyCreationParamters | |
) | |
} | |
} | |
catch [CryptographicException] { | |
if (!$CurrentUser -and "Access denied.`r`n" -eq $_.ToString()) { | |
throw "Access denied: try running as admin" | |
} | |
throw $_ | |
} | |
if ($ECDSA) { | |
$csr = [X509Certificates.CertificateRequest]::new( | |
$DistinguishedName, | |
[ECDsaCng]::new($key), | |
[HashAlgorithmName]::SHA256 | |
) | |
} | |
else { | |
$csr = [X509Certificates.CertificateRequest]::new( | |
$DistinguishedName, | |
[RSACng]::new($key), | |
[HashAlgorithmName]::SHA256, | |
[RSASignaturePadding]::Pkcs1 | |
) | |
} | |
$sanBuilder = [X509Certificates.SubjectAlternativeNameBuilder]::new() | |
foreach ($dnsName in $dnsNames) { | |
$sanBuilder.AddDnsName($dnsName) | |
} | |
foreach ($ipAddress in $ipAddresses) { | |
$sanBuilder.AddIpAddress($ipAddress) | |
} | |
# SAN-utvidelsen skal være kritisk hvis | |
# vi ikke har med emne i sertifikatet. | |
$sanExt = $sanBuilder.Build($NoSubject) | |
$csr.CertificateExtensions.Add($sanExt) | |
# Vi må genererer et selvsignert sertifikat | |
# og lagre i storen, så Windows skjønner | |
# at det ferdige sertifikatet skal kobles | |
# opp mot nøkkelen. | |
$cert = $csr.CreateSelfSigned( | |
[System.DateTimeOffset]::UtcNow, | |
[System.DateTimeOffset]::UtcNow.AddYears(1) | |
) | |
if ($CurrentUser) { | |
$store = [X509Certificates.StoreLocation]::CurrentUser | |
} | |
else { | |
$store = [X509Certificates.StoreLocation]::LocalMachine | |
} | |
$store = [X509Certificates.X509Store]::new( | |
"REQUEST", | |
$store | |
) | |
$store.open([X509Certificates.OpenFlags]::ReadWrite) | |
try { | |
$store.add($cert) | |
} | |
finally { | |
$store.close() | |
} | |
$base64encodedCsr = [Convert]::ToBase64String($csr.CreateSigningRequest()) | |
$pemCsr = "-----BEGIN CERTIFICATE REQUEST-----`r`n" | |
$i = 0 | |
foreach ($char in $base64encodedCsr.ToCharArray()) { | |
if ($i -eq 64) { | |
$pemCsr += "`r`n$char" | |
$i = 0 | |
} | |
else { | |
$pemCsr += $char | |
} | |
$i += 1 | |
} | |
$pemCsr += "`r`n-----END CERTIFICATE REQUEST-----" | |
Write-Output "Generated key and CSR:" | |
Write-Output "" | |
Write-Output $pemCsr |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment