Private/New-PAKey.ps1

function New-PAKey {
    [CmdletBinding()]
    param(
        [Parameter(Position=0)]
        [ValidateScript({Test-ValidKeyLength $_ -ThrowOnFail})]
        [string]$KeyLength='2048',
        [switch]$AsJwk,
        [switch]$AsPrettyJwk
    )

    # RFC Note: 'kty' is case-sensitive
    # https://tools.ietf.org/html/rfc7517#section-4.1

    # KeyLength should have already been validated which means it should be a parseable
    # [int] that may have an "ec-" prefix
    if ($KeyLength -like 'ec-*') {
        $KeyType = 'EC'
        $KeySize = [int]::Parse($KeyLength.Substring(3))
    } else {
        $KeyType = 'RSA'
        $KeySize = [int]::Parse($KeyLength)
    }
    Write-Debug "Creating new $KeyType $KeySize key"

    # create the new key
    switch ($KeyType) {
        'RSA' {
            $Key = New-Object Security.Cryptography.RSACryptoServiceProvider $KeySize
            break;
        }
        'EC' {
            # Use Curves created via OID because CreateFromFriendlyName wasn't working very well
            # cross-platform.
            # https://msdn.microsoft.com/en-us/library/windows/desktop/mt632245(v=vs.85).aspx
            switch ($KeySize) {
                256 {
                    # nistP256 / secP256r1 / x962P256v1
                    $Curve = [Security.Cryptography.ECCurve]::CreateFromValue('1.2.840.10045.3.1.7')
                    $HashAlgo = [Security.Cryptography.CngAlgorithm]::SHA256
                    break;
                }
                384 {
                    # secP384r1
                    $Curve = [Security.Cryptography.ECCurve]::CreateFromValue('1.3.132.0.34')
                    $HashAlgo = [Security.Cryptography.CngAlgorithm]::SHA384
                    break;
                }
                521 {
                    # secP521r1
                    $Curve = [Security.Cryptography.ECCurve]::CreateFromValue('1.3.132.0.35')
                    $HashAlgo = [Security.Cryptography.CngAlgorithm]::SHA512
                    break;
                }
                default { throw "Unsupported EC KeySize. Try 256, 384, or 521." }
            }
            $Key = [Security.Cryptography.ECDsa]::Create($Curve)
            $Key.HashAlgorithm = $HashAlgo
            break;
        }
        default { throw "Unsupported key type" }
    }

    if ($AsPrettyJwk) {
        return ($Key | ConvertTo-Jwk -AsPrettyJson)
    } elseif ($AsJson) {
        return ($Key | ConvertTo-Jwk -AsJson)
    } else {
        return $Key
    }
}