https://www.thesecmaster.com/procedure-to-install-openssl-on-the-windows-platform/
https://slproweb.com/download/Win64OpenSSL_Light-3_0_1.msi
Export-PfxCertificate
Extracting Certificate and Private Key Files from a .pfx File
Extract certificate to PFX then to CRT and KEY
Detta skript hämtar certifikat där Subject innehåller det som skickats med som argument. Resultatet sorteras på slutdatum och det certifikatet med senaste slutdatum väljs. Detta är det första utkastet jag skrev och skriptet har sina begränsningar då det inte tar höjd för certifikat med multipla DNS-namn. Detta skript körs i powershell kommandorad.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$name = $Script:args | Select-Object -First 1 # find latest (by expire date) cert matching argument $cert=Get-ChildItem Cert:\LocalMachine\My\ | where {$_.Subject -like "*$name*"} | sort NotAfter | select -Last 1 # extract certname from subject name $certname = ($cert.DnsNameList | where {$_.punycode -notmatch "\*"}).Unicode # convert password to secure string $pwd = ConvertTo-SecureString -String "1q2w3e" -Force -AsPlainText # Export certificate to .PFX file including private key $cert | Export-PfxCertificate -FilePath "$($certname).pfx" -Password $pwd # Save private key to temporary file "$(ConvertFrom-SecureString $pwd -AsPlainText)" | openssl pkcs12 -in "$($certname).pfx" -nocerts -out "$($certname).key.pem" -nodes -passin 'stdin' # Export full chain certificates to .CRT file "$(ConvertFrom-SecureString $pwd -AsPlainText)" | openssl pkcs12 -in "$($certname).pfx" -nokeys -out "$($certname).crt" -passin 'stdin' # save key without password openssl rsa -in "$($certname).key.pem" -out "$($certname).key" rm "$($certname).key.pem" |
Detta skript är en vidareutveckling av skriptet ovan. Här extraherar vi namnet från FriendlyName. Detta används sedan för namning av skapade filer. Detta skript körs i powershell kommandorad.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
param ( [string] $name, [string] $password="", [switch] $exportCRT ) if ( !$name ) { Write-Host -ForegroundColor Red "Noting to do! Exiting." Write-Host -ForegroundColor Green "Add part of Subject name in certifificate you want to export.`r`n" Write-Host -ForegroundColor Yellow "Ex 1) .\certexp.ps1 -name sandblom.it => Exports certificate containing 'sandblom.it' in Subject to PFX file`r`n" Write-Host -ForegroundColor Yellow "Ex 2) .\certexp.ps1 -name sandblom.it -exportCRT => Same as above,`r`n`t`tPLUS: a certificate file (CRT) and private key file (KEY) is generated`r`n" Write-Host -ForegroundColor Yellow "Use the switch -password 'passwordOfYourChoice' to use your own password" break } # find latest (by expire date) cert matching argument $cert = Get-ChildItem Cert:\LocalMachine\My\ | where {$_.Subject -like "*$name*"} | sort NotAfter | select -Last 1 # extract certname from subject name # $certname = ($cert.DnsNameList | where {$_.punycode -notmatch "\*"}).Unicode $certname = $cert.FriendlyName -split ' ' | Select-Object -First 1 # convert password to secure string if ($password -ne '') { $pwd = ConvertTo-SecureString -String $password -Force -AsPlainText } else { $pwd = ConvertTo-SecureString -String "1q2w3e" -Force -AsPlainText } # Export certificate to .PFX file including private key $cert | Export-PfxCertificate -FilePath "$($certname).pfx" -Password $pwd if ( $exportCRT.isPresent ) { Switch ( $host.Version.Major ) { 5 { $pwdcleartxt = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR( $pwd )) } 7 { $pwdcleartxt = ConvertFrom-SecureString -SecureString $pwd -AsPlainText } } # Save private key to temporary file $pwdcleartxt | openssl pkcs12 -in "$($certname).pfx" -nocerts -out "$($certname).key.pem" -nodes -passin 'stdin' # Export full chain certificates to .CRT file $pwdcleartxt | openssl pkcs12 -in "$($certname).pfx" -nokeys -out "$($certname).crt" -passin 'stdin' # save key without password openssl rsa -in "$($certname).key.pem" -out "$($certname).key" rm "$($certname).key.pem" } |
GUI
Ovanstående skript är konstruerat för att köras från en Powershell kommandorad. Följande skript består av två filer. En CertExp.XAML-fil som innehåller WPF XAML kod som beskriver uppbyggnaden av gränsnittet. Denna tas fram genom att skapa ett WPF-projekt i Visual Studio och där bygga upp gräsnittet så som det önskas. Efter att man är nöjd (detta är givetvis en iterativ process, sällan man träffar rätt på första försöket) så kopierar man ut XAML-koden från projektet och detta kan antingen sparas inline i powershell-skriptet eller som jag valt här i en egen fil. Nästa fil är själva powershell-skriptet där man först laddar XAML-koden från tidigare nämd fil och sedan fyller man på med den logik som önskas.
I samma mapp som CertExp.ps1 och CertExp.xaml (se nedan) så läggs två D´LL-filer samt en EXE-fil för OpenSSL, dessa finns att ladda ner i länk nedan.
OpenSSL v3 ZIP ( Direktlänk )
OpenSSL nerladdning (Starsida)
CertExp.XAML
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="Certificate Extraction and Export Powershell GUI Tool" Height="630" Width="810" MinWidth="810" MinHeight="630" Background="#FFDEE8F0"> <Grid> <TextBox x:Name="FriendlyName_Tbx" Height="30" Margin="105,144,216,0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0"/> <TextBox x:Name="Thumbprint_Tbx" Height="30" Margin="105,109,216,0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0"/> <TextBox x:Name="Subject_Tbx" Height="30" Margin="105,39,216,0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0"/> <Label x:Name="FriendlyName_Lbl" Content="FriendlyName" HorizontalAlignment="Left" Margin="10,144,0,0" VerticalAlignment="Top" Padding="0" Height="30" Width="90" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <Label x:Name="Thumbprint_Lbl" Content="Thumbprint" HorizontalAlignment="Left" Margin="10,109,0,0" VerticalAlignment="Top" Padding="0" Height="30" Width="90" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <Label x:Name="Subject_Lbl" Content="Subject" HorizontalAlignment="Left" Margin="10,39,0,0" VerticalAlignment="Top" Padding="0" Height="30" Width="90" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <Label x:Name="label1" Content="Certificate Extraction and Export Powershell GUI Tool" VerticalAlignment="Top" FontSize="16" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Background="#BFA8C0DC" FontWeight="Bold" FontStyle="Italic"/> <TabControl x:Name="tabControl" Margin="10,254,10,60" Background="#3FFFFFFF"> <TabItem x:Name="CertList_Tab" Header="Certlist"> <Grid> <DataGrid x:Name="CertList_DGrid" Margin="4" Background="#26FFFFFF" BorderBrush="#26688CAF"/> </Grid> </TabItem> <TabItem x:Name="Filepaths_Tab" Header="Filepaths"> <Grid> <Label x:Name="PFXFilename_Lbl" Content="PFX file name" HorizontalAlignment="Left" Margin="20,23,0,0" VerticalAlignment="Top" Padding="0,0,0,2" Width="120" Height="32" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <TextBox x:Name="PFXFilename_Tbx" Margin="145,23,208,0" TextWrapping="Wrap" VerticalAlignment="Top" Padding="8,2,0,2" BorderBrush="#FF0078D7" Height="30" FontSize="14" VerticalContentAlignment="Center"/> <Label x:Name="CRTFilename_Lbl" Content="CRT file name" HorizontalAlignment="Left" Margin="20,58,0,0" VerticalAlignment="Top" Padding="0,4,0,2" Width="120" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <TextBox x:Name="CRTFilename_Tbx" Margin="145,58,208,0" TextWrapping="Wrap" VerticalAlignment="Top" Padding="8,2,0,2" BorderBrush="#FF0078D7" Height="30" FontSize="14" VerticalContentAlignment="Center"/> <Label x:Name="InterimKEYFilename_Lbl" Content="Interim KEY file name" HorizontalAlignment="Left" Margin="20,93,0,0" VerticalAlignment="Top" Padding="0,4,0,2" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Width="120"/> <TextBox x:Name="InterimKEYFilename_Tbx" Margin="145,93,208,0" TextWrapping="Wrap" VerticalAlignment="Top" Padding="8,2,0,2" BorderBrush="#FF0078D7" Height="30" FontSize="14" VerticalContentAlignment="Center"/> <Label x:Name="KEYFilename_Lbl" Content="KEY file name" HorizontalAlignment="Left" Margin="20,128,0,0" VerticalAlignment="Top" Padding="0,4,0,2" Width="120" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <TextBox x:Name="KEYFilename_Tbx" Margin="145,128,208,0" TextWrapping="Wrap" VerticalAlignment="Top" Padding="8,2,0,2" BorderBrush="#FF0078D7" Height="30" FontSize="14" VerticalContentAlignment="Center"/> <Label x:Name="Password_Lbl" Content="Password" HorizontalAlignment="Left" Margin="20,163,0,0" VerticalAlignment="Top" Padding="0,4,0,2" Width="120" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <TextBox x:Name="Password_Tbx" Margin="145,163,208,0" TextWrapping="Wrap" VerticalAlignment="Top" Padding="8,2,0,2" BorderBrush="#FF0078D7" Height="30" FontSize="14" VerticalContentAlignment="Center"/> <Grid HorizontalAlignment="Right" Margin="0,94,7,0" VerticalAlignment="Top" Width="196"> <CheckBox x:Name="ExportCRTSwitch_Ckx" Content="Export CRT and KEY file" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,20,0,0"/> <CheckBox x:Name="PasswordParam_Ckx" Content="Use own password" HorizontalAlignment="Left" Margin="20,40,0,0" VerticalAlignment="Top"/> </Grid> <Button x:Name="ExportCert_Btn" Content="Export from Certificate store" HorizontalAlignment="Right" Margin="0,23,7,0" VerticalAlignment="Top" Width="196" Height="30" Background="#BFA8C0DC" ToolTip="Exports certificate based on 'Certificate Name' from local Certificate store"/> <Button x:Name="ExtractCertFromPFX_Btn" Content="Extract CRT and KEY from PFX file" HorizontalAlignment="Right" Margin="0,59,7,0" VerticalAlignment="Top" Width="196" Height="30" Background="#BFA8C0DC" ToolTip="Extracts CRT and KEY file from PFX file listed below"/> <Button x:Name="OpenCertsFolder_Btn" Content="Open Certificates folder" HorizontalAlignment="Right" Margin="0,163,7,0" VerticalAlignment="Top" Height="30" Background="#BFA8C0DC" ToolTip="Open folder containing exported Certificates" Width="196"/> </Grid> </TabItem> </TabControl> <Button x:Name="OpenCERTLMMSC_BTN" Content="Open Cert Mgr Cmp Store (MSC)" HorizontalAlignment="Right" Margin="0,74,10,0" VerticalAlignment="Top" Width="196" Height="30" Background="#BFA8C0DC" ToolTip="Open Certificate Manager Computer Store (MSC)"/> <Button x:Name="OpenCERTMGRMSC_BTN" Content="Open Cert Mgr Usr Store (MSC)" HorizontalAlignment="Right" Margin="0,109,10,0" VerticalAlignment="Top" Width="196" Height="30" Background="#BFA8C0DC" ToolTip="Open Certificate Manager Usr Store (MSC)"/> <ComboBox x:Name="CertStoreLocation_Cbx" HorizontalAlignment="Right" Margin="0,39,10,0" VerticalAlignment="Top" Width="196" Height="30" FontSize="14" SelectedIndex="0"/> <Label x:Name="Status_Lbl" Content="" Margin="10,0,10,10" VerticalAlignment="Bottom" Height="45" VerticalContentAlignment="Center" Padding="0" HorizontalContentAlignment="Center" FontSize="14" Foreground="Green"/> <TextBox x:Name="SerialNumber_Tbx" Height="30" Margin="105,74,216,0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0"/> <Label x:Name="SerialNumber_Lbl" Content="Serialnumber" HorizontalAlignment="Left" Margin="10,74,0,0" VerticalAlignment="Top" Padding="0" Height="30" Width="90" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <Grid Height="30" Margin="10,179,216,0" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="95" /> <ColumnDefinition /> <ColumnDefinition Width="76" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Label x:Name="NotBefore_Lbl" Content="NotBefore" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Padding="0" Height="30" Width="90" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/> <TextBox x:Name="NotBefore_Tbx" Height="30" Margin="0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0" Grid.Column="1"/> <Label x:Name="NotAfter_Lbl" Content="NotAfter" VerticalAlignment="Top" Padding="20,0,0,0" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Column="2" HorizontalAlignment="Left"/> <TextBox x:Name="NotAfter_Tbx" Height="30" Margin="0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0" Grid.Column="3"/> </Grid> <Grid Height="30" Margin="10,214,216,0" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="95" /> <ColumnDefinition /> <ColumnDefinition Width="76" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ComboBox x:Name="DnsNameList_Cbx" Margin="0" VerticalAlignment="Top" Height="30" FontSize="14" Grid.Column="1"/> <Label x:Name="DnsNameList_Lbl" Content="DnsNameList" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Padding="0" Height="30" Width="90" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Column="0"/> <Label x:Name="Certname_Lbl" Content="Name" HorizontalAlignment="Left" VerticalAlignment="Top" Padding="0" Height="30" Width="66" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Column="2"/> <TextBox x:Name="DnsNameList_Tbx" Height="30" Margin="0,0,18,0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0" Grid.Column="1"/> <TextBox x:Name="Certname_Tbx" Height="30" Margin="0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" FontSize="14" Padding="4,0,0,0" Grid.Column="3"/> </Grid> </Grid> </Window> |
CertExp.ps1
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
if ( $host.name -eq "Windows PowerShell ISE Host" ) { $filename = $psISE.CurrentFile.FullPath.Replace(".ps1",".xaml") } else { $filename = $MyInvocation.MyCommand.Path.Replace(".ps1",".xaml") } $scriptpath = $filename -replace ($filename -split "\\" | Select-Object -Last 1),"" [xml]$xaml = Get-Content $filename -Raw [void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework') #[void][System.Windows.Forms.Application]::EnableVisualStyles() Add-Type -AssemblyName Microsoft.VisualBasic $reader=(New-Object System.Xml.XmlNodeReader $xaml) try { $Form=[Windows.Markup.XamlReader]::Load( $reader ) } catch { Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta,invalid XAML code was encountered."t } # Load nodes from XAML source and create variables $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach { New-Variable -Name $_.Name -Value $Form.FindName($_.Name) -Force } function move-window { param( [int]$newX, [int]$newY ) BEGIN { $signature = @' [DllImport("user32.dll")] public static extern bool MoveWindow( IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool GetWindowRect( HandleRef hWnd, out RECT lpRect); public struct RECT { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner public int Right; // x position of lower-right corner public int Bottom; // y position of lower-right corner } '@ Add-Type -MemberDefinition $signature -Name Wutils -Namespace WindowsUtils } PROCESS{ $phandle = [WindowsUtils.Wutils]::GetForegroundWindow() $o = New-Object -TypeName System.Object $href = New-Object -TypeName System.RunTime.InteropServices.HandleRef -ArgumentList $o, $phandle $rct = New-Object WindowsUtils.Wutils+RECT [WindowsUtils.Wutils]::GetWindowRect($href, [ref]$rct) $width = $rct.Right - $rct.Left $height = 800 <# $height = $rct.Bottom = $rct.Top $rct.Right $rct.Left $rct.Bottom $rct.Top $width $height #> [WindowsUtils.Wutils]::MoveWindow($phandle, $newX, $newY, $width, $height, $true) } } function GeneratePassword () { function Scramble-String([string]$inputString){ $characterArray = $inputString.ToCharArray() $scrambledStringArray = $characterArray | Get-Random -Count $characterArray.Length $outputString = -join $scrambledStringArray return $outputString } function Get-RandomCharacters($length, $characters) { $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length } $private:ofs="" return [String]$characters[$random] } $password = Get-RandomCharacters -length 13 -characters 'abcdefghiklmnoprstuvwxyzABCDEFGHKLMNOPRSTUVWXYZ1234567890!@#' $password = Scramble-String $password $password = Scramble-String $password return [string]$password } function SaveSortedCRT () { param( [Parameter(Mandatory)] [string] $OriginalCRTFilepath ) <# #> # Get RAW content of the CRT file, we want it in a single string $certfile = Get-Content -Path $OriginalCRTFilepath -Raw # Regex expression to match the indiviual certificate blocks $regexPattern = 'Bag Attributes(\s*|.*)*subject=(.*)\sissuer=(.*)\s([-]*BEGIN CERTIFICATE[-]*\s(([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})|\s)+\s[-]*END CERTIFICATE[-]*)' # Get the matches $matches = Select-String -Pattern $regexPattern -InputObject $certfile -AllMatches | ForEach-Object { $_.Matches } # Identify Root CA Certificate, based on the fact that subject and issuer is the same $CertRootCA = $matches | where { ($_.value -replace $regexPattern,'$2' ) -eq ($_.value -replace $regexPattern,'$3' ) } # Identify Intermediate CA Certificate, based on the fact it's issued by Root CA Certificate # Exclude the match where Subject matches Issuer since Root CA Certificate is issued by itself $CertCA = $matches | where { ($_.value -replace $regexPattern,'$3' ) -eq (($CertRootCA).value -replace $regexPattern,'$2' ) -and ($_.value -replace $regexPattern,'$2' ) -ne ($_.value -replace $regexPattern,'$3' ) } # Identify Certificate, based on the facts it's issued by Intermediate CA $Cert = $matches | where { ($_.value -replace $regexPattern,'$3' ) -eq (($CertCA).value -replace $regexPattern,'$2' ) } # Filepath to store unsorted CRT $unSortedCRTFilePath = $OriginalCRTFilepath -replace '.crt','-unsorted.crt' # Rename original CRT file Move-Item -Path $OriginalCRTFilepath -Destination $unSortedCRTFilePath # Save sorted content to Original CRT Filepath $Cert.Value + "`r`n" + $CertCA.Value + "`r`n" + $CertRootCA.Value | Out-File -FilePath $OriginalCRTFilepath -Encoding UTF8 } $Status_Lbl.FontSize = 13 $Status_Lbl.Content = "Current: " + (Invoke-Expression "$($scriptpath)openssl version") $localcomputercertlist = Get-ChildItem Cert:\LocalMachine\My\ | select * | Sort-Object FriendlyName $currentusercertlist = Get-ChildItem Cert:\CurrentUser\My\ | select * | Sort-Object FriendlyName $CertList_DGrid.ItemsSource = $localcomputercertlist | Select-Object Subject,Thumbprint,SerialNumber,NotBefore,NotAfter,DnsNameList,FriendlyName $ExportCert_Btn.IsEnabled = $false $ExtractCertFromPFX_Btn.IsEnabled = $false $ExportCRTSwitch_Ckx.IsEnabled = $false $PasswordParam_Ckx.Visibility = "Hidden" [void] $CertStoreLocation_Cbx.Items.Add("LocalMachine") [void] $CertStoreLocation_Cbx.Items.Add("CurrentUser") $CertStoreLocation_Cbx.Add_SelectionChanged({ switch ( $CertStoreLocation_Cbx.SelectedIndex ) { 0 {$CertList_DGrid.ItemsSource = $localcomputercertlist | Select-Object Subject,Thumbprint,SerialNumber,NotBefore,NotAfter,DnsNameList,FriendlyName} 1 {$CertList_DGrid.ItemsSource = $currentusercertlist | Select-Object Subject,Thumbprint,SerialNumber,NotBefore,NotAfter,DnsNameList,FriendlyName} } $CertList_Tab.Focus() $FriendlyName_Tbx.Text = "" $Thumbprint_Tbx.Text = "" $SerialNumber_Tbx.Text = "" $NotBefore_Tbx.Text = "" $NotAfter_Tbx.Text = "" $Subject_Tbx.Text = "" $DnsNameList_Cbx.Items.Clear() }) $OpenCERTLMMSC_BTN.Add_Click({ Invoke-Expression -Command 'certlm.msc' $Status_Lbl.Content = "CERTLM.MSC opened!" }) $OpenCERTMGRMSC_BTN.Add_Click({ Invoke-Expression -Command 'certmgr.msc' $Status_Lbl.Content = "CERTMGR.MSC opened!" }) $CertList_DGrid.Add_SelectionChanged({ $i = $CertList_DGrid.SelectedIndex if ( $CertStoreLocation_Cbx.SelectedIndex -eq 0 ) { $FriendlyName_Tbx.Text = $localcomputercertlist[$i].FriendlyName $Thumbprint_Tbx.Text = $localcomputercertlist[$i].Thumbprint $SerialNumber_Tbx.Text = $localcomputercertlist[$i].SerialNumber $NotBefore_Tbx.Text = $localcomputercertlist[$i].NotBefore $NotAfter_Tbx.Text = $localcomputercertlist[$i].NotAfter $Subject_Tbx.Text = $localcomputercertlist[$i].Subject $DnsNameList_Cbx.Items.Clear() foreach ( $entry in ($localcomputercertlist[$i].DnsNameList | where {$_.unicode -notmatch "\*"})){ $DnsNameList_Cbx.Items.Add( $entry.Unicode ) } $Status_Lbl.Content = "Certificate ""$($FriendlyName_Tbx.Text)"" selected.`r`nChoose from DNSNameList dropdown list!" } if ( $CertStoreLocation_Cbx.SelectedIndex -eq 1 ) { $FriendlyName_Tbx.Text = $currentusercertlist[$i].FriendlyName $Thumbprint_Tbx.Text = $currentusercertlist[$i].Thumbprint $SerialNumber_Tbx.Text = $currentusercertlist[$i].SerialNumber $NotBefore_Tbx.Text = $currentusercertlist[$i].NotBefore $NotAfter_Tbx.Text = $currentusercertlist[$i].NotAfter $Subject_Tbx.Text = $currentusercertlist[$i].Subject $DnsNameList_Cbx.Items.Clear() foreach ( $entry in ($currentusercertlist[$i].DnsNameList)){ $DnsNameList_Cbx.Items.Add( $entry.Unicode ) } } $ExportCert_Btn.IsEnabled = $false $ExportCRTSwitch_Ckx.IsChecked = $false $ExportCRTSwitch_Ckx.IsEnabled = $false if ( $DnsNameList_Cbx.Items.Count -eq 1 ) { $DnsNameList_Cbx.SelectedIndex = 0 } $Filepaths_Tab.Focus() }) $DnsNameList_Cbx.Add_SelectionChanged({ $DnsNameList_Tbx.Text = $DnsNameList_Cbx.SelectedValue }) $DnsNameList_Tbx.Add_TextChanged({ $Certname_Tbx.Text = $DnsNameList_Tbx.Text }) $Certname_Tbx.Add_TextChanged({ if( !(Test-Path "$($scriptpath)Certs" ) ) {mkdir "$($scriptpath)Certs" } if( $Certname_Tbx.Text -ne '' ) { $PFXFilename_Tbx.Text = $scriptpath + "Certs\" + $Certname_Tbx.Text + ".pfx" $CRTFilename_Tbx.Text = $scriptpath + "Certs\" + $Certname_Tbx.Text + ".crt" $InterimKEYFilename_Tbx.Text = $scriptpath + "Certs\" + $Certname_Tbx.Text + ".pem.key" $KEYFilename_Tbx.Text = $scriptpath + "Certs\" + $Certname_Tbx.Text + ".key" $Password_Tbx.Text = GeneratePassword $ExportCert_Btn.IsEnabled = $true $Status_Lbl.Content = "Filepaths generated based on scriptpath and CertName!" } else { $PFXFilename_Tbx.Text = "" $CRTFilename_Tbx.Text = "" $InterimKEYFilename_Tbx.Text = "" $KEYFilename_Tbx.Text = "" $Password_Tbx.Text = "" $ExportCert_Btn.IsEnabled = $false $Status_Lbl.Content = "No CertName given clearing filepaths!" } $PFXFilename_Tbx.Background = "white" $CRTFilename_Tbx.Background = "white" $KEYFilename_Tbx.Background = "white" $InterimKEYFilename_Tbx.Background = "white" }) # Invoke-Item "$($scriptpath)certs" $OpenCertsFolder_Btn.Add_Click({ Invoke-Item "$($scriptpath)certs" }) $ExportCert_Btn.Add_Click({ $localcomputercertlist[ $CertList_DGrid.SelectedIndex ] | Export-PfxCertificate -FilePath $PFXFilename_Tbx.Text -Password (ConvertTo-SecureString -String $Password_Tbx.Text -AsPlainText -Force) $Password_Tbx.Text | Out-File -FilePath "$($PFXFilename_Tbx.Text)-pwd.txt" -Encoding utf8 -Force -Confirm:$false if ( Test-Path $PFXFilename_Tbx.Text ) { $PFXFilename_Tbx.Background = "lightgreen" $ExportCRTSwitch_Ckx.IsEnabled = $true $Status_Lbl.Content = "PFX-file ""$($PFXFilename_Tbx.Text -split "\\" | Select-Object -Last 1)"" exported to ""$($scriptpath)""!`r`nCheck ""$($ExportCRTSwitch_Ckx.Content)"" to enable extraction." } }) $ExtractCertFromPFX_Btn.Add_Click({ # Save private key to temporary file $cmdstr = "echo $($Password_Tbx.Text) | $($scriptpath)openssl pkcs12 -in $($PFXFilename_Tbx.Text) -nocerts -out $($InterimKEYFilename_Tbx.Text) -nodes -passin 'stdin'" Invoke-Expression -Command $cmdstr # save key without password $cmdstr = "$($scriptpath)openssl rsa -in $($InterimKEYFilename_Tbx.Text) -out $($KEYFilename_Tbx.Text)" Invoke-Expression -Command $cmdstr # Export full chain certificates to .CRT file $cmdstr = "echo $($Password_Tbx.Text) | $($scriptpath)openssl pkcs12 -in $($PFXFilename_Tbx.Text) -nokeys -out $($CRTFilename_Tbx.Text) -passin 'stdin'" Invoke-Expression -Command $cmdstr # Save a sorted CRT and rename the original to 'unsorted' SaveSortedCRT -OriginalCRTFilepath $CRTFilename_Tbx.Text rm $InterimKEYFilename_Tbx.Text if ( Test-Path $CRTFilename_Tbx.Text ) { $CRTFilename_Tbx.Background = "lightgreen" $Status_Lbl.Content = "CRT-file ""$($CRTFilename_Tbx.Text -split "\\" | Select-Object -Last 1)"" and " } if ( Test-Path $InterimKEYFilename_Tbx.Text ) { $InterimKEYFilename_Tbx.Background = "lightgreen" } if ( Test-Path $KEYFilename_Tbx.Text ) { $KEYFilename_Tbx.Background = "lightgreen" $Status_Lbl.Content = $Status_Lbl.Content + "KEY-file ""$($KEYFilename_Tbx.Text -split "\\" | Select-Object -Last 1)"" extracted to ""$($scriptpath)""!" } }) #$PasswordParam_Ckx.Add_Checked({}) #$PasswordParam_Ckx.Add_UnChecked({}) $ExportCRTSwitch_Ckx.Add_Checked({ $ExtractCertFromPFX_Btn.IsEnabled = $true }) $ExportCRTSwitch_Ckx.Add_UnChecked({ $ExtractCertFromPFX_Btn.IsEnabled = $false }) # move form to specific screen position, x,y $Form.Add_loaded({ move-window 20 20 }) # check if executed in Windows Powershell ISE, if not resize console if ( $host.name -eq "ConsoleHost" ) { move-window 20 820 [console]::WindowWidth=78; [console]::WindowHeight=5; [console]::BufferWidth=[console]::WindowWidth } [void]$Form.ShowDialog() |