add new powershell files

This commit is contained in:
William Cheng 2020-05-09 15:10:54 +08:00
parent 2b1bc73f03
commit b81a9fa4f4
2 changed files with 545 additions and 0 deletions

View File

@ -0,0 +1,168 @@
#
# OpenAPI Petstore
# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
# Version: 1.0.0
# Generated by OpenAPI Generator: https://openapi-generator.tech
#
<#
.SYNOPSIS
Get the API key Id and API key file path.
.DESCRIPTION
Get the API key Id and API key file path. If no api prefix is provided then it use default api key prefix 'Signature'
.OUTPUTS
PSCustomObject : This contains APIKeyId, APIKeyFilePath, APIKeyPrefix
#>
function Get-PSAPIKeyInfo {
$ApiKeysList = $Script:Configuration['ApiKey']
$ApiKeyPrefixList = $Script:Configuration['ApiKeyPrefix']
$apiPrefix = "Signature"
if ($null -eq $ApiKeysList -or $ApiKeysList.Count -eq 0) {
throw "Unable to reterieve the api key details"
}
if ($null -eq $ApiKeyPrefixList -or $ApiKeyPrefixList.Count -eq 0) {
Write-Verbose "Unable to reterieve the api key prefix details,setting it to default ""Signature"""
}
foreach ($item in $ApiKeysList.GetEnumerator()) {
if (![string]::IsNullOrEmpty($item.Name)) {
if (Test-Path -Path $item.Value) {
$apiKey = $item.Value
$apikeyId = $item.Name
break;
}
else {
throw "API key file path does not exist."
}
}
}
if ($ApiKeyPrefixList.ContainsKey($apikeyId)) {
$apiPrefix = ApiKeyPrefixList[$apikeyId]
}
if ($apikeyId -and $apiKey -and $apiPrefix) {
$result = New-Object -Type PSCustomObject -Property @{
ApiKeyId = $apikeyId;
ApiKeyFilePath = $apiKey
ApiKeyPrefix = $apiPrefix
}
}
else {
return $null
}
return $result
}
<#
.SYNOPSIS
Gets the headers for http signed auth.
.DESCRIPTION
Gets the headers for the http signed auth. It use (targetpath), date, host and body digest to create authorization header.
.PARAMETER Method
Http method
.PARAMETER UriBuilder
UriBuilder for url and query parameter
.PARAMETER Body
Request body
.OUTPUTS
Hashtable
#>
function Get-PSHttpSignedHeader {
param(
[string]$Method,
[System.UriBuilder]$UriBuilder,
[string]$Body
)
#Hash table to store singed headers
$HttpSignedHeader = @{}
$TargetHost = $UriBuilder.Host
#Check for Authentication type
$apiKeyInfo = Get-PSAPIKeyInfo
if ($null -eq $apiKeyInfo) {
throw "Unable to reterieve the api key info "
}
#get the body digest
$bodyHash = Get-PSStringHash -String $Body
$Digest = [String]::Format("SHA-256={0}", [Convert]::ToBase64String($bodyHash))
#get the date in UTC
$dateTime = Get-Date
$currentDate = $dateTime.ToUniversalTime().ToString("r")
$requestTargetPath = [string]::Format("{0} {1}{2}",$Method.ToLower(),$UriBuilder.Path.ToLower(),$UriBuilder.Query)
$h_requestTarget = [string]::Format("(request-target): {0}",$requestTargetPath)
$h_cdate = [string]::Format("date: {0}",$currentDate)
$h_digest = [string]::Format("digest: {0}",$Digest)
$h_targetHost = [string]::Format("host: {0}",$TargetHost)
$stringToSign = [String]::Format("{0}`n{1}`n{2}`n{3}",
$h_requestTarget,$h_cdate,
$h_targetHost,$h_digest)
$hashedString = Get-PSStringHash -String $stringToSign
$signedHeader = Get-PSRSASHA256SignedString -APIKeyFilePath $apiKeyInfo.ApiKeyFilePath -DataToSign $hashedString
$authorizationHeader = [string]::Format("{0} keyId=""{1}"",algorithm=""rsa-sha256"",headers=""(request-target) date host digest"",signature=""{2}""",
$apiKeyInfo.ApiKeyPrefix, $apiKeyInfo.ApiKeyId, $signedHeader)
$HttpSignedHeader["Date"] = $currentDate
$HttpSignedHeader["Host"] = $TargetHost
$HttpSignedHeader["Content-Type"] = "application/json"
$HttpSignedHeader["Digest"] = $Digest
$HttpSignedHeader["Authorization"] = $authorizationHeader
return $HttpSignedHeader
}
<#
.SYNOPSIS
Gets the headers for http signed auth.
.DESCRIPTION
Gets the headers for the http signed auth. It use (targetpath), date, host and body digest to create authorization header.
.PARAMETER APIKeyFilePath
Specify the API key file path
.PARAMETER DataToSign
Specify the data to sign
.OUTPUTS
String
#>
function Get-PSRSASHA256SignedString {
Param(
[string]$APIKeyFilePath,
[byte[]]$DataToSign
)
try {
$rsa_provider_path = Join-Path -Path $PSScriptRoot -ChildPath "PSRSAEncryptionProvider.cs"
$rsa_provider_sourceCode = Get-Content -Path $rsa_provider_path -Raw
Add-Type -TypeDefinition $rsa_provider_sourceCode
$signed_string = [RSAEncryption.RSAEncryptionProvider]::GetRSASignb64encode($APIKeyFilePath, $DataToSign)
if ($null -eq $signed_string) {
throw "Unable to sign the header using the API key"
}
return $signed_string
}
catch {
throw $_
}
}
<#
.Synopsis
Gets the hash of string.
.Description
Gets the hash of string
.Outputs
String
#>
Function Get-PSStringHash([String] $String, $HashName = "SHA256") {
$hashAlogrithm = [System.Security.Cryptography.HashAlgorithm]::Create($HashName)
$hashAlogrithm.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))
}

View File

@ -0,0 +1,377 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
namespace RSAEncryption
{
public class RSAEncryptionProvider
{
const String pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
const String pemprivfooter = "-----END RSA PRIVATE KEY-----";
const String pempubheader = "-----BEGIN PUBLIC KEY-----";
const String pempubfooter = "-----END PUBLIC KEY-----";
const String pemp8header = "-----BEGIN PRIVATE KEY-----";
const String pemp8footer = "-----END PRIVATE KEY-----";
const String pemp8encheader = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
const String pemp8encfooter = "-----END ENCRYPTED PRIVATE KEY-----";
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
/*Console.WriteLine("showing components ..");
if (true)
{
showBytes("\nModulus", MODULUS);
showBytes("\nExponent", E);
showBytes("\nD", D);
showBytes("\nP", P);
showBytes("\nQ", Q);
showBytes("\nDP", DP);
showBytes("\nDQ", DQ);
showBytes("\nIQ", IQ);
}*/
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception)
{
return null;
}
finally { binr.Close(); }
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
}
while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current);
//last ReadByte wasn't a removed zero, so back up a byte
return count;
}
static byte[] DecodeOpenSSLPrivateKey(String instr)
{
const String pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
const String pemprivfooter = "-----END RSA PRIVATE KEY-----";
String pemstr = instr.Trim();
byte[] binkey;
if (!pemstr.StartsWith(pemprivheader) || !pemstr.EndsWith(pemprivfooter))
return null;
StringBuilder sb = new StringBuilder(pemstr);
sb.Replace(pemprivheader, ""); //remove headers/footers, if present
sb.Replace(pemprivfooter, "");
String pvkstr = sb.ToString().Trim(); //get string after removing leading/trailing whitespace
try
{ // if there are no PEM encryption info lines, this is an UNencrypted PEM private key
binkey = Convert.FromBase64String(pvkstr);
return binkey;
}
catch (System.FormatException)
{ //if can't b64 decode, it must be an encrypted private key
//Console.WriteLine("Not an unencrypted OpenSSL PEM private key");
}
StringReader str = new StringReader(pvkstr);
//-------- read PEM encryption info. lines and extract salt -----
if (!str.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED"))
return null;
String saltline = str.ReadLine();
if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,"))
return null;
String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim();
byte[] salt = new byte[saltstr.Length / 2];
for (int i = 0; i < salt.Length; i++)
salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16);
if (!(str.ReadLine() == ""))
return null;
//------ remaining b64 data is encrypted RSA key ----
String encryptedstr = str.ReadToEnd();
try
{ //should have b64 encrypted RSA key now
binkey = Convert.FromBase64String(encryptedstr);
}
catch (System.FormatException)
{ // bad b64 data.
return null;
}
//------ Get the 3DES 24 byte key using PDK used by OpenSSL ----
SecureString despswd = GetSecPswd("Enter password to derive 3DES key==>");
//Console.Write("\nEnter password to derive 3DES key: ");
//String pswd = Console.ReadLine();
byte[] deskey = GetOpenSSL3deskey(salt, despswd, 1, 2); // count=1 (for OpenSSL implementation); 2 iterations to get at least 24 bytes
if (deskey == null)
return null;
//showBytes("3DES key", deskey) ;
//------ Decrypt the encrypted 3des-encrypted RSA private key ------
byte[] rsakey = DecryptKey(binkey, deskey, salt); //OpenSSL uses salt value in PEM header also as 3DES IV
if (rsakey != null)
return rsakey; //we have a decrypted RSA private key
else
{
Console.WriteLine("Failed to decrypt RSA private key; probably wrong password.");
return null;
}
}
static byte[] GetOpenSSL3deskey(byte[] salt, SecureString secpswd, int count, int miter)
{
IntPtr unmanagedPswd = IntPtr.Zero;
int HASHLENGTH = 16; //MD5 bytes
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store contatenated Mi hashed results
byte[] psbytes = new byte[secpswd.Length];
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
//UTF8Encoding utf8 = new UTF8Encoding();
//byte[] psbytes = utf8.GetBytes(pswd);
// --- contatenate salt and pswd bytes into fixed data array ---
byte[] data00 = new byte[psbytes.Length + salt.Length];
Array.Copy(psbytes, data00, psbytes.Length); //copy the pswd bytes
Array.Copy(salt, 0, data00, psbytes.Length, salt.Length); //concatenate the salt bytes
// ---- do multi-hashing and contatenate results D1, D2 ... into keymaterial bytes ----
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = null;
byte[] hashtarget = new byte[HASHLENGTH + data00.Length]; //fixed length initial hashtarget
for (int j = 0; j < miter; j++)
{
// ---- Now hash consecutively for count times ------
if (j == 0)
result = data00; //initialize
else
{
Array.Copy(result, hashtarget, result.Length);
Array.Copy(data00, 0, hashtarget, result.Length, data00.Length);
result = hashtarget;
//Console.WriteLine("Updated new initial hash target:") ;
//showBytes(result) ;
}
for (int i = 0; i < count; i++)
result = md5.ComputeHash(result);
Array.Copy(result, 0, keymaterial, j * HASHLENGTH, result.Length); //contatenate to keymaterial
}
//showBytes("Final key material", keymaterial);
byte[] deskey = new byte[24];
Array.Copy(keymaterial, deskey, deskey.Length);
Array.Clear(psbytes, 0, psbytes.Length);
Array.Clear(data00, 0, data00.Length);
Array.Clear(result, 0, result.Length);
Array.Clear(hashtarget, 0, hashtarget.Length);
Array.Clear(keymaterial, 0, keymaterial.Length);
return deskey;
}
public static string GetRSASignb64encode(string private_key_path, byte[] digest)
{
RSACryptoServiceProvider cipher = new RSACryptoServiceProvider();
cipher = GetRSAProviderFromPemFile(private_key_path);
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(cipher);
RSAFormatter.SetHashAlgorithm("SHA256");
byte[] signedHash = RSAFormatter.CreateSignature(digest);
return Convert.ToBase64String(signedHash);
}
public static RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile)
{
bool isPrivateKeyFile = true;
if (!File.Exists(pemfile))
{
throw new Exception("pemfile does not exist.");
}
string pemstr = File.ReadAllText(pemfile).Trim();
if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
isPrivateKeyFile = false;
byte[] pemkey = null;
if (isPrivateKeyFile)
pemkey = DecodeOpenSSLPrivateKey(pemstr);
if (pemkey == null)
return null;
if (isPrivateKeyFile)
{
return DecodeRSAPrivateKey(pemkey);
}
return null;
}
static byte[] DecryptKey(byte[] cipherData, byte[] desKey, byte[] IV)
{
MemoryStream memst = new MemoryStream();
TripleDES alg = TripleDES.Create();
alg.Key = desKey;
alg.IV = IV;
try
{
CryptoStream cs = new CryptoStream(memst, alg.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(cipherData, 0, cipherData.Length);
cs.Close();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
return null;
}
byte[] decryptedData = memst.ToArray();
return decryptedData;
}
static SecureString GetSecPswd(String prompt)
{
SecureString password = new SecureString();
Console.ForegroundColor = ConsoleColor.Gray;
Console.ForegroundColor = ConsoleColor.Magenta;
while (true)
{
ConsoleKeyInfo cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.Enter)
{
Console.ForegroundColor = ConsoleColor.Gray;
return password;
}
else if (cki.Key == ConsoleKey.Backspace)
{
// remove the last asterisk from the screen...
if (password.Length > 0)
{
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
password.RemoveAt(password.Length - 1);
}
}
else if (cki.Key == ConsoleKey.Escape)
{
Console.ForegroundColor = ConsoleColor.Gray;
return password;
}
else if (Char.IsLetterOrDigit(cki.KeyChar) || Char.IsSymbol(cki.KeyChar))
{
if (password.Length < 20)
{
password.AppendChar(cki.KeyChar);
}
else
{
Console.Beep();
}
}
else
{
Console.Beep();
}
}
}
}
}