frechekatze
Goto Top

C Sharp - Code to Powershell

Hallo, zurzeit setzte ich mich mit Powershell auseinander, oder viel mehr Lerne ich es, mithilfe von Google Suche und eBooks.
Jetzt habe ich Testshalber ein C# - Code in Powershell umgeschrieben,
aber die Länge des Rückgabewertes mit 128 Zeichen stimmt nicht mit der Länge der Funktion von 108 Zeichen überein.

Ich denke das es an [Array]::Copy liegen könnte...?

Frage: Muss man bei Powershell irgendeine Methode aufrufen, oder Speicher leeren damit es funktioniert,

Der Rückgabewert der Funktion soll am Ende 128 Zeichen lang sein, wie beim C# - Code.

Ich bedanke mich schon mal an alle, die mir hier weiter helfen können.

Mein Test Script:

using namespace System
using namespace System.IO
using namespace System.Text
using namespace System.Security.Cryptography

Add-Type @'  
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace AesEncrypt
{
    public abstract class WithHmac
    {
        public static readonly int BlockBitSize = 128;
        public static readonly int KeyBitSize = 256;
        public static readonly int SaltBitSize = 64;
        public static readonly int Iterations = 10000;

        public static string Encrypt(string secretMessage, string password, byte nonSecretPayload = null)
        {
            var plainText = Encoding.UTF8.GetBytes(secretMessage);
            var cipherText = Encrypt(plainText, password, nonSecretPayload);
            return Convert.ToBase64String(cipherText);
        }

        public static byte Encrypt(
            byte secretMessage, 
            byte cryptKey, 
            byte authKey,
            byte nonSecretPayload = null
        )
        {
            nonSecretPayload = nonSecretPayload ?? new byte { };
            byte cipherText;
            byte iv;
            using (var aes = new AesManaged
            {
                KeySize = KeyBitSize,
                BlockSize = BlockBitSize,
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            })
            {
                aes.GenerateIV();
                iv = aes.IV;
                using (var encrypter = aes.CreateEncryptor(cryptKey, iv))
                using (var cipherStream = new MemoryStream())
                {
                    using (var cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
                    using (var binaryWriter = new BinaryWriter(cryptoStream))
                    {
                        binaryWriter.Write(secretMessage);
                    }

                    cipherText = cipherStream.ToArray();
                }
            }
            using (var hmac = new HMACSHA256(authKey))
            using (var encryptedStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(encryptedStream))
                {
                    binaryWriter.Write(nonSecretPayload);
                    binaryWriter.Write(iv);
                    binaryWriter.Write(cipherText);
                    binaryWriter.Flush();
                    var tag = hmac.ComputeHash(encryptedStream.ToArray());
                    binaryWriter.Write(tag);
                }
                return encryptedStream.ToArray();
            }
        }

        public static byte Encrypt(
	        byte secretMessage, 
	        string password,
            byte nonSecretPayload = null
	    )
        {
            nonSecretPayload = nonSecretPayload ?? new byte { };
            var payload = new byte[((SaltBitSize / 8) * 2) + nonSecretPayload.Length];
            Array.Copy(nonSecretPayload, payload, nonSecretPayload.Length);
            int payloadIndex = nonSecretPayload.Length;
            byte cryptKey;
            byte authKey;
            using (var generator = new Rfc2898DeriveBytes(password, SaltBitSize / 8, Iterations))
            {
                var salt = generator.Salt;
                cryptKey = generator.GetBytes(KeyBitSize / 8);
                Array.Copy(salt, 0, payload, payloadIndex, salt.Length);
                payloadIndex += salt.Length;
            }            
            using (var generator = new Rfc2898DeriveBytes(password, SaltBitSize / 8, Iterations))
            {
                var salt = generator.Salt;
                authKey = generator.GetBytes(KeyBitSize / 8);
                Array.Copy(salt, 0, payload, payloadIndex, salt.Length);
            }
            return Encrypt(secretMessage, cryptKey, authKey, payload);
        }
    }
}
'@  

[Hashtable] $BitSize = @{ 
    Iterations = 10000
    Key   = 256
    Block = 128    
    Salt  = 64
}

Function AES
{
    return New-Object -TypeName AesManaged -Property @{
        BlockSize = 128
        KeySize   = 256  
        Padding   = [PaddingMode]::PKCS7
        Mode      = [CipherMode]::CBC 
    } 
}

Function Encrypt-String ([string] $secretMessage, [string] $password, [byte[]] $nonSecretPayload = $null) {

    $plainText = [Encoding]::UTF8.GetBytes($secretMessage)

    if ($nonSecretPayload -eq $null) { $nonSecretPayload = New-Object byte 0 } else {
        $nonSecretPayload = New-Object byte $nonSecretPayload
    }
    
    $payload = New-Object byte ((($BitSize.Salt / 8) * 2) + $nonSecretPayload.Length)
    [Array]::Copy($nonSecretPayload, $payload, $nonSecretPayload.Length)
    [int] $payloadIndex = $nonSecretPayload.Length

    [Rfc2898DeriveBytes] $generator = New-Object Rfc2898DeriveBytes ($password, ($BitSize.Salt / 8), $BitSize.Iterations)
    $salt = $generator.Salt
    $cryptKey = $generator.GetBytes(($BitSize.Key / 8))
    [Array]::Copy($salt, 0, $payload, $payloadIndex, $salt.Length)
    $payloadIndex = ($payloadIndex + $salt.Length)
    $generator.Dispose()

    [Rfc2898DeriveBytes] $generator = New-Object Rfc2898DeriveBytes ($password, ($BitSize.Salt / 8), $BitSize.Iterations)
    $salt = $generator.Salt
    $authKey = $generator.GetBytes(($BitSize.Key / 8))
    [Array]::Copy($salt, 0, $payload, $payloadIndex, $salt.Length)
    $generator.Dispose()

    try
    {
        [AesManaged] $aes = AES
        $aes.GenerateIV()    
        $iv = $aes.IV

        $cipherStream = New-Object MemoryStream
        [CryptoStream] $cryptoStream = New-Object CryptoStream @($cipherStream, $aes.CreateEncryptor($cryptKey, $iv), [CryptoStreamMode]::Write)
        [BinaryWriter] $binaryWriter = New-Object BinaryWriter ($cryptoStream)
        $binaryWriter.Write($plainText)    

    } 
    catch { throw $_ }
    finally
    {
        if ($binaryWriter) { $binaryWriter.Close() }
        if ($cryptoStream) { $cryptoStream.Close() }
        if ($cipherStream) { $cipherStream.Close() }
        if ($aes)          { $aes.Dispose() }
    }

    $cipherText = $cipherStream.ToArray()

    try
    {
        [HMACSHA256] $hmac = New-Object HMACSHA256
        $hmac.Key = $authKey
        $encryptedStream = New-Object MemoryStream
        [BinaryWriter] $binaryWriter = New-Object BinaryWriter ($encryptedStream)
        $binaryWriter.Write($nonSecretPayload)
        $binaryWriter.Write($iv)
        $binaryWriter.Write($cipherText)
        $binaryWriter.Flush()
        $tag = $hmac.ComputeHash($encryptedStream.ToArray())
        $binaryWriter.Write($tag)
    } 
    catch { throw $_ }
    finally
    {
        if ($binaryWriter)    { $binaryWriter.Close() }
        if ($encryptedStream) { $encryptedStream.Close() }
        if ($hmac)            { $hmac.Dispose() }
    }  
    
    return [Convert]::ToBase64String($encryptedStream.ToArray()) 
}

$Password = "LLVeDd0dMrYw784TQdRtzpE3Wx@9o75R5OjN/=="  
$Message  = "Bla Bla Blub...."  

[AesEncrypt.WithHmac]::Encrypt($Message, $Password).length # 128 Zeichen lang
(Encrypt-String $Message $Password).length # 108 Zeichen lang

Content-Key: 350009

Url: https://administrator.de/contentid/350009

Printed on: April 26, 2024 at 13:04 o'clock

Mitglied: 133883
133883 Sep 25, 2017 updated at 11:55:04 (UTC)
Goto Top
Stichwort Länge des Salts face-wink

Gruß

P.s. PowerShell + FTP in EXE
Member: FrecheKatze
FrecheKatze Sep 25, 2017 at 12:39:50 (UTC)
Goto Top
Habe jetzt den fehler gefunden. So schussellig wie ich bin!

Zeile 178: Ich habe "nonSecretPayload" anstelle von "payload" verwendet, deshalb bekam nur 108 Zeichen.

Zeile 101: return Encrypt(secretMessage, cryptKey, authKey, payload);
Zeile 178: $binaryWriter.Write($payload) 

Ein Dank auch an Oneplus und allen anderen die sich hier die Zeit genommen haben.