A little bit outdated. I know.
But customers not always have the latest server versions running.
Today a customer asked me how to create a self signed SSL certificate with “subject alternate names” (SAN) using PowerShell on Windows Server 2012 R2.
The default cmdlet “New-SelfSignedCertificate” has not all features on this server OS.
The customer found a script but it did not offer SAN. I found another one (in german language) that gave me the other information…
Sources:
https://www.symplasson.de/it-blog/san-erweiterung-csr-windows-ca
I assembled both scripts. Here is the result.
# script assembled from these sources
# - https://docs.microsoft.com/en-us/archive/blogs/vishalagarwal/generating-a-certificate-self-signed-using-powershell-and-certenroll-interfaces
# - https://www.symplasson.de/it-blog/san-erweiterung-csr-windows-ca
# …by Ingo Karstein ( ik a.t. kenaro.com)
#
# Useful e.g. on Windows Server 2012R2 because there are less functionality in cmdlet New-SelfSignedCertificate.
#
# The SSL cert ist written to certstore "My" of "LocalMachine"
$name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
$name.Encode("CN=srv", 0)
$key = new-object -com "X509Enrollment.CX509PrivateKey.1"
$key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
$key.KeySpec = 1
$key.Length = 4096
$key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
$key.MachineContext = 1
$key.Create()
$serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
$serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")
$AlternativeNames=@("srv", "localhost")
$AlternativeIPs=@("127.0.0.1", "::1")
$SAN = New-Object -ComObject X509Enrollment.CX509ExtensionAlternativeNames
$IANs = New-Object -ComObject X509Enrollment.CAlternativeNames
foreach ($SANstr in $AlternativeNames)
{
$IAN = New-Object -ComObject X509Enrollment.CAlternativeName
$IAN.InitializeFromString(0x3,$SANstr)
$IANs.Add($IAN)
}
foreach ($SANstr in $AlternativeIPs)
{
$IAN = New-Object -ComObject X509Enrollment.CAlternativeName
$IAN.InitializeFromString(0x3,$SANstr)
$IANs.Add($IAN)
$IAI = New-Object -ComObject X509Enrollment.CAlternativeName
$IAI.InitializeFromRawData(8, 0x1,
[Convert]::ToBase64String(
([System.Net.IpAddress] $SANstr).GetAddressBytes())) $IANs.Add($IAI)
}
$SAN.InitializeEncode($IANs)
$ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
$ekuoids.add($serverauthoid)
$ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
$ekuext.InitializeEncode($ekuoids)
$cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
$cert.InitializeFromPrivateKey(2, $key, "")
$cert.Subject = $name
$cert.Issuer = $cert.Subject
$cert.NotBefore = (get-date).AddDays(-1)
$cert.NotAfter = $cert.NotBefore.Addyears(50)
$cert.X509Extensions.Add($ekuext)
$cert.X509Extensions.Add($SAN)
$cert.Encode()
$enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
$enrollment.InitializeFromRequest($cert)
$certdata = $enrollment.CreateRequest(0)
$enrollment.InstallResponse(2, $certdata, 0, "")