|
function New-SelfSignedRootCertificate { |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory = $true)] |
|
[string] $Name, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[string] $CertStoreLocation, |
|
|
|
[Parameter()] |
|
[datetime] $NotAfter = (Get-Date).AddYears(50) |
|
) |
|
|
|
$cert = New-SelfSignedCertificate ` |
|
-Subject "$Name Certificate Authority" ` |
|
-FriendlyName "$Name Certificate Authority" ` |
|
-CertStoreLocation $CertStoreLocation ` |
|
-KeyUsage KeyEncipherment, DataEncipherment, CertSign ` |
|
-KeyUsageProperty Sign ` |
|
-HashAlgorithm SHA256 ` |
|
-KeyLength 4096 ` |
|
-TextExtension @("2.5.29.19 ={critical}{text}CA=1&pathlength=3") ` |
|
-NotAfter $NotAfter |
|
|
|
Get-Item "Cert:\LocalMachine\CA\$($cert.Thumbprint)" | Move-Item -Destination Cert:\LocalMachine\Root -ErrorAction Stop | Out-Null |
|
|
|
Write-Output $cert |
|
} |
|
|
|
function New-SelfSignedIntermediateCertificate { |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory = $true)] |
|
[string] $Name, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[string] $CertStoreLocation, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[System.Security.Cryptography.X509Certificates.X509Certificate2] $SigningCertificate, |
|
|
|
[Parameter()] |
|
[datetime] $NotAfter = (Get-Date).AddYears(25) |
|
) |
|
|
|
$cert = New-SelfSignedCertificate ` |
|
-Subject "$Name Intermediate Authority" ` |
|
-FriendlyName "$Name Intermediate Authority" ` |
|
-CertStoreLocation $CertStoreLocation ` |
|
-Signer $SigningCertificate ` |
|
-KeyUsage KeyEncipherment, DataEncipherment, CertSign ` |
|
-KeyUsageProperty Sign ` |
|
-HashAlgorithm SHA256 ` |
|
-KeyLength 4096 ` |
|
-TextExtension @("2.5.29.19 ={critical}{text}CA=1&pathlength=0") ` |
|
-NotAfter $NotAfter |
|
|
|
Write-Output $cert |
|
} |
|
|
|
function Install-SelfSignedDevelopmentCertificateAuthority { |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory = $true)] |
|
[string]$Name, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[securestring]$PrivateKeyPassword, |
|
|
|
[Parameter()] |
|
[switch]$NoEndEntityCertificate |
|
) |
|
|
|
$root = New-SelfSignedRootCertificate -Name $Name -CertStoreLocation Cert:\LocalMachine\My |
|
Write-Host "Root Certificate = Cert:\LocalMachine\Root\$($root.Thumbprint)" -ForegroundColor Cyan |
|
|
|
$intermediate = New-SelfSignedIntermediateCertificate -Name $Name -CertStoreLocation Cert:\LocalMachine\My -SigningCertificate $root |
|
Write-Host "Intermediate Certificate = Cert:\LocalMachine\CA\$($intermediate.Thumbprint)" -ForegroundColor Cyan |
|
|
|
if (-not $NoEndEntityCertificate) { |
|
$edge = New-SelfSignedCertificate ` |
|
-CertStoreLocation Cert:\LocalMachine\My ` |
|
-DnsName "localhost", $env:COMPUTERNAME ` |
|
-NotAfter (Get-Date).AddYears(5) ` |
|
-FriendlyName "Local Development Certificate" ` |
|
-Signer $intermediate |
|
|
|
Write-Host "End Entity Certificate = Cert:\LocalMachine\My\$($edge.Thumbprint)" -ForegroundColor Cyan |
|
} |
|
|
|
$keydir = "$env:USERPROFILE\.$($name.ToLower() -replace ' ')" |
|
if (-not (Test-Path $keydir)) { mkdir $keydir | Out-Null } |
|
|
|
|
|
Write-Host -NoNewline "Exporting key material to '$keydir'..." |
|
@($intermediate, $root) | ForEach-Object { |
|
Export-PfxCertificate -Cert $_ -FilePath "$keydir\$($_.Subject -replace 'CN=','').pfx" -Password $PrivateKeyPassword | Out-Null |
|
Remove-Item $_.PSPath -DeleteKey | Out-Null |
|
} |
|
Write-Host Done! |
|
} |
|
|
|
|
|
# WIP |
|
# function Uninstall-SelfSignedDevelopmentCertificateAuthority { |
|
# [CmdletBinding()] |
|
# param( |
|
# [Parameter(Mandatory = $true)] |
|
# [string]$Name |
|
# ) |
|
|
|
# $root = Get-ChildItem Cert:\LocalMachine\ -Recurse -DnsName "$Name Certificate Authority" |
|
|
|
# $intermediate = Get-ChildItem Cert:\LocalMachine -Recurse | Where-Object Issuer -eq $root[0].Subject |
|
|
|
# $edge = Get-ChildItem Cert:\LocalMachine\My, Cert:\CurrentUser\My ` |
|
# | Where-Object Issuer -eq $intermediate[0].Subject |
|
|
|
# $edge + $intermediate + $root | ForEach-Object { Write-Verbose "Removing $($_.PSPath)" | Remove-Item $_ } |
|
# } |
|
|
|
|
|
Export-ModuleMember -Function * |
That is how I used it. I haven't used in quite sometime though. I just use
dotnet dev-certs
to generate my dev certificate now.