|
| 1 | +function New-RSAKeyPair { |
| 2 | + <# |
| 3 | + .SYNOPSIS |
| 4 | + Generates an RSA PEM key pair and corresponding public SSH key. |
| 5 | +
|
| 6 | + .DESCRIPTION |
| 7 | + Generates an RSA PEM key pair and corresponding public SSH key. |
| 8 | +
|
| 9 | + .PARAMETER Length |
| 10 | + Alias: [-l,-b] |
| 11 | + The bit-length of the key to generate. Defaults to 4096. |
| 12 | +
|
| 13 | + .PARAMETER Password |
| 14 | + Alias: -p |
| 15 | + A SecureString or plain-text String containing the password to encrypt the private key with. Exclude to create the private key without a password. For security, SecureString is recommended, although plain-text strings are allowed for broader compatibility. |
| 16 | +
|
| 17 | + .PARAMETER Path |
| 18 | + Alias: -out |
| 19 | + The path to save the private key to. Defaults to ~/.ssh/id_rsa |
| 20 | +
|
| 21 | + .PARAMETER Interactive |
| 22 | + Alias: -i |
| 23 | + If $true, prompt the user for the options to create the key with. Similar to creating a key with ssh-keygen. |
| 24 | +
|
| 25 | + .PARAMETER NoFile |
| 26 | + Alias: -nof |
| 27 | + If $true, do not save any keys to file. Sets PassThru to $true and returns the generated RSAKey object containing the PublicPEM, PublicSSH, and PrivatePEM as string properties. |
| 28 | +
|
| 29 | + .PARAMETER NoSSH |
| 30 | + Alias: -nos |
| 31 | + If $true, do not save the SSH key to file. Use when only the RSA PEM key pair is needed. |
| 32 | +
|
| 33 | + .PARAMETER NoPEM |
| 34 | + Alias: -nop |
| 35 | + If $true, do not save the Public PEM key to file. Use when only the SSH key pair is needed. |
| 36 | +
|
| 37 | + .PARAMETER PassThru |
| 38 | + Alias: -pt |
| 39 | + Returns the generated RSAKey object containing the PublicPEM, PublicSSH, and PrivatePEM as string properties. |
| 40 | +
|
| 41 | + .PARAMETER Force |
| 42 | + Alias: -f |
| 43 | + If the keys at the file path already exist, overwrite them. |
| 44 | +
|
| 45 | + .EXAMPLE |
| 46 | + New-RSAKeyPair -Interactive |
| 47 | +
|
| 48 | + Generating public/private RSA key pair... |
| 49 | + Enter the path to save the key to (Default: C:\Users\nate\.ssh\id_rsa): .\Testing\id_pemencrypt |
| 50 | + Enter desired key length (Default: 4096): |
| 51 | + Enter passphrase (Default: No passphrase): |
| 52 | + Saving private key to path : .\Testing\id_pemencrypt |
| 53 | + Saving public SSH key to path : .\Testing\id_pemencrypt.pub |
| 54 | + Saving public PEM key to path : .\Testing\id_pemencrypt.pem |
| 55 | +
|
| 56 | + .EXAMPLE |
| 57 | + New-RSAKeyPair -NoFile |
| 58 | +
|
| 59 | + PublicPEM |
| 60 | + --------- |
| 61 | + -----BEGIN PUBLIC KEY-----... |
| 62 | +
|
| 63 | + .EXAMPLE |
| 64 | + New-RSAKeyPair -Length 1024 -NoFile | Select-Object -ExpandProperty PublicSSH |
| 65 | + ssh-rsa AAAAB3NzaC1yc2EAAAABAwAAAIEAo2CDoZRSy7JDJbX3ygsj3L09rMxq+46lMkWv6K33Cng3y4DokqqyUc2KCzhspBViGzVl3mJ+Y4S9O+D4bktcSDRZbEmZ0cVsFZFEAI17iEKnZHZnaqMIoIzaK2TS0rnQbkYpSDfKUAZtwSNiWB0TfMFdnOY6UJdlfLGzPeFJWTU= PEMEncrypt@User@Computer |
| 66 | +
|
| 67 | + .EXAMPLE |
| 68 | + New-RSAKeyPair |
| 69 | + Key already exists at desired path: C:\Users\nate\.ssh\id_rsa. Use -Force to overwrite the existing key or choose a different path. |
| 70 | + At E:\Git\PEMEncrypt\BuildOutput\PEMEncrypt\0.2.0\PEMEncrypt.psm1:177 char:21 |
| 71 | + + ... throw "Key already exists at desired path: $Path. Use -Fo ... |
| 72 | + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 73 | + + CategoryInfo : OperationStopped: (Key already exists \u2026e a different path.:String) [], RuntimeException |
| 74 | + + FullyQualifiedErrorId : Key already exists at desired path: C:\Users\nate\.ssh\id_rsa. Use -Force to overwrite the existing key or choose a different path. |
| 75 | + #> |
| 76 | + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] |
| 77 | + [OutputType('SCRTHQ.PEMEncrypt.RSAKey')] |
| 78 | + [CmdletBinding()] |
| 79 | + Param( |
| 80 | + [Parameter(Position = 0)] |
| 81 | + [Alias('l','b')] |
| 82 | + [Int] |
| 83 | + $Length = 4096, |
| 84 | + [parameter()] |
| 85 | + [Alias('p')] |
| 86 | + [Object] |
| 87 | + $Password, |
| 88 | + [parameter()] |
| 89 | + [Alias('out')] |
| 90 | + [String] |
| 91 | + $Path = (Get-DefaultPath), |
| 92 | + [Parameter()] |
| 93 | + [Alias('i')] |
| 94 | + [Switch] |
| 95 | + $Interactive, |
| 96 | + [Parameter()] |
| 97 | + [Alias('nof')] |
| 98 | + [Switch] |
| 99 | + $NoFile, |
| 100 | + [Parameter()] |
| 101 | + [Alias('nos')] |
| 102 | + [Switch] |
| 103 | + $NoSSH, |
| 104 | + [Parameter()] |
| 105 | + [Alias('nop')] |
| 106 | + [Switch] |
| 107 | + $NoPEM, |
| 108 | + [Parameter()] |
| 109 | + [Alias('pt')] |
| 110 | + [Switch] |
| 111 | + $PassThru, |
| 112 | + [Parameter()] |
| 113 | + [Alias('f')] |
| 114 | + [Switch] |
| 115 | + $Force |
| 116 | + ) |
| 117 | + Begin { |
| 118 | + Import-Assemblies |
| 119 | + if ($MyInvocation.InvocationName -eq 'genrsa') { |
| 120 | + $NoPEM = $false |
| 121 | + $NoSSH = $true |
| 122 | + } |
| 123 | + if ($MyInvocation.InvocationName -eq 'genssh') { |
| 124 | + $NoSSH = $false |
| 125 | + $NoPEM = $true |
| 126 | + } |
| 127 | + } |
| 128 | + Process { |
| 129 | + if ($Interactive) { |
| 130 | + Write-Host "Generating public/private RSA key pair..." |
| 131 | + if (-not $NoFile) { |
| 132 | + $newPath = if ($choice = Read-Host -Prompt "Enter the path to save the key to (Default: $Path)") { |
| 133 | + $choice |
| 134 | + } |
| 135 | + else { |
| 136 | + $Path |
| 137 | + } |
| 138 | + if (-not $Force -and (Test-Path $newPath)) { |
| 139 | + throw "Key already exists at desired path: $newPath. Use -Force to overwrite the existing key or choose a different path" |
| 140 | + } |
| 141 | + } |
| 142 | + $Length = if ($choice = Read-Host -Prompt "Enter desired key bit length (Default: 4096)") { |
| 143 | + $choice |
| 144 | + } |
| 145 | + else { |
| 146 | + 4096 |
| 147 | + } |
| 148 | + $Password = Read-Host -AsSecureString -Prompt "Enter passphrase (Default: No passphrase)" |
| 149 | + if (-not ([System.String]::IsNullOrEmpty((Unprotect-SecureString -SecureString $Password)))) { |
| 150 | + $confirmed = Read-Host -AsSecureString -Prompt "Enter the same passphrase to confirm" |
| 151 | + if ((Unprotect-SecureString -SecureString $confirmed) -ne (Unprotect-SecureString -SecureString $Password)) { |
| 152 | + Write-Warning "Passphrases provided do not match! Exiting" |
| 153 | + throw |
| 154 | + } |
| 155 | + $keys = [SCRTHQ.PEMEncrypt.RSA]::Generate( |
| 156 | + $Length, |
| 157 | + (Unprotect-SecureString -SecureString $Password) |
| 158 | + ) |
| 159 | + } |
| 160 | + else { |
| 161 | + $keys = [SCRTHQ.PEMEncrypt.RSA]::Generate( |
| 162 | + $Length |
| 163 | + ) |
| 164 | + } |
| 165 | + if (-not $NoFile) { |
| 166 | + Write-Host "Saving private key to path : $newPath" |
| 167 | + $keys.PrivatePEM | Set-Content -Path $newPath -Force |
| 168 | + if (-not $NoSSH) { |
| 169 | + $sshPath = "{0}.pub" -f $newPath |
| 170 | + Write-Host "Saving public SSH key to path : $sshPath" |
| 171 | + $keys.PublicSSH | Set-Content -Path $sshPath -Force |
| 172 | + } |
| 173 | + if (-not $NoPEM) { |
| 174 | + $pemPath = "{0}.pem" -f $newPath |
| 175 | + Write-Host "Saving public PEM key to path : $pemPath" |
| 176 | + $keys.PublicPEM | Set-Content -Path $pemPath -Force |
| 177 | + } |
| 178 | + } |
| 179 | + if ($PassThru -or $NoFile) { |
| 180 | + $keys |
| 181 | + } |
| 182 | + } |
| 183 | + else { |
| 184 | + $keys = if ($PSBoundParameters.ContainsKey('Password')) { |
| 185 | + [SCRTHQ.PEMEncrypt.RSA]::Generate( |
| 186 | + $Length, |
| 187 | + $(if($Password -is [SecureString]){(Unprotect-SecureString -SecureString $Password)}else{"$Password"}) |
| 188 | + ) |
| 189 | + } |
| 190 | + else { |
| 191 | + [SCRTHQ.PEMEncrypt.RSA]::Generate( |
| 192 | + $Length |
| 193 | + ) |
| 194 | + } |
| 195 | + if (-not $NoFile) { |
| 196 | + if (-not $Force -and (Test-Path $Path)) { |
| 197 | + throw "Key already exists at desired path: $Path. Use -Force to overwrite the existing key or choose a different path." |
| 198 | + } |
| 199 | + else { |
| 200 | + Write-Host "Saving private key to path : $Path" |
| 201 | + $keys.PrivatePEM | Set-Content -Path $Path -Force |
| 202 | + if (-not $NoSSH) { |
| 203 | + $sshPath = "{0}.pub" -f $Path |
| 204 | + Write-Host "Saving public SSH key to path : $sshPath" |
| 205 | + $keys.PublicSSH | Set-Content -Path $sshPath -Force |
| 206 | + } |
| 207 | + if (-not $NoPEM) { |
| 208 | + $pemPath = "{0}.pem" -f $Path |
| 209 | + Write-Host "Saving public PEM key to path : $pemPath" |
| 210 | + $keys.PublicPEM | Set-Content -Path $pemPath -Force |
| 211 | + } |
| 212 | + } |
| 213 | + } |
| 214 | + if ($PassThru -or $NoFile) { |
| 215 | + $keys |
| 216 | + } |
| 217 | + } |
| 218 | + } |
| 219 | +} |
0 commit comments