Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
powershell.rsa_provider.mustache Maven / Gradle / Ivy
/*
{{#appName}}
* {{{.}}}
*
{{/appName}}
{{#appDescription}}
* {{{.}}}
*
{{/appDescription}}
{{#version}}
* The version of the OpenAPI document: {{{.}}}
{{/version}}
{{#infoEmail}}
* Contact: {{{.}}}
{{/infoEmail}}
* Generated by: https://github.com/openapitools/openapi-generator.git
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
namespace RSAEncryption
{
///
/// A RSA enccryption provider.
///
public class RSAEncryptionProvider
{
///
/// Get the RSA provider from the PEM file.
///
/// PEM file.
/// Key pass phrase.
/// Get an instance of RSACryptoServiceProvider.
public static RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile,SecureString keyPassPhrase = null)
{
const String pempubheader = "-----BEGIN PUBLIC KEY-----";
const String pempubfooter = "-----END PUBLIC KEY-----";
bool isPrivateKeyFile = true;
byte[] pemkey = null;
if (!File.Exists(pemfile))
{
throw new Exception("private key file does not exist.");
}
string pemstr = File.ReadAllText(pemfile).Trim();
if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
{
isPrivateKeyFile = false;
}
if (isPrivateKeyFile)
{
pemkey = ConvertPrivateKeyToBytes(pemstr,keyPassPhrase);
if (pemkey == null)
{
return null;
}
return DecodeRSAPrivateKey(pemkey);
}
return null ;
}
///
/// Convert the private key to bytes.
///
/// Private key.
/// Key pass phrase.
/// The private key in the form of bytes.
static byte[] ConvertPrivateKeyToBytes(String instr, SecureString keyPassPhrase = null)
{
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, "");
sb.Replace(pemprivfooter, "");
String pvkstr = sb.ToString().Trim();
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)
{
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)
{ //data is not in base64 format
return null;
}
byte[] deskey = GetEncryptedKey(salt, keyPassPhrase, 1, 2); // count=1 (for OpenSSL implementation); 2 iterations to get at least 24 bytes
if (deskey == null)
{
return null;
}
//------ 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
return rsakey;
}
}
///
/// Decode the RSA private key.
///
/// Private key.
/// An instance of RSACryptoServiceProvider.
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] bytesModules, bytesE, bytesD, bytesP, bytesQ, bytesDp, bytesDq, bytesIq;
// --------- 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);
bytesModules = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesE = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesD = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesDp = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesDq = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
bytesIq = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = bytesModules;
RSAparams.Exponent = bytesE;
RSAparams.D = bytesD;
RSAparams.P = bytesP;
RSAparams.Q = bytesQ;
RSAparams.DP = bytesDp;
RSAparams.DQ = bytesDq;
RSAparams.InverseQ = bytesIq;
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;
}
///
/// Get the encrypted key.
///
/// Random bytes to be added.
/// Password.
/// Count.
/// Miter.
/// Decrypted key.
static byte[] GetEncryptedKey(byte[] salt, SecureString secpswd, int count, int miter)
{
IntPtr unmanagedPswd = IntPtr.Zero;
const int HASHLENGTH = 16; //MD5 bytes
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store concatenated Mi hashed results
byte[] psbytes = new byte[secpswd.Length];
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
// --- concatenate 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 concatenate 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;
}
for (int i = 0; i < count; i++)
{
result = md5.ComputeHash(result);
}
Array.Copy(result, 0, keymaterial, j * HASHLENGTH, result.Length); //concatenate to 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;
}
///
/// Decrypt the key.
///
/// Cipher data.
/// Key to decrypt.
/// Initialization vector.
/// Decrypted key.
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)
{
return null;
}
byte[] decryptedData = memst.ToArray();
return decryptedData;
}
}
}