kokosik 1221
kokosik 1221

Reputation: 29

C# AES Encryption Need

I have an Encrypted string and function to decrypt it. Now I need to edit this string and encrypt it. When I use this function to encrypt and decrypt in result strings are not the same.

Orginal encrypted string:

APpuC6G3f3cUKaAuOFXOGIo9rwz/+fQ0tBCi6Fk40THVnIT+au7JXkOQHdgPcpQ3VUrXw69rIL+QRsHea5+Q6TxOeuAnzkU8c3UClx6Toe+jOIVi3DlkLIGzE8DmyBArtZYpKTOt4rrOSDyLKifdgcM+MgwuJbDXyXVuQyp2C42zZ1ETPUOF2TSIZKhnMSR43FFy8WEbpKBAjkPmgVpqqhrjabu+JHbj7kPIxGGjDHGaCCyCtFwsk3264Lv4GTp049SCjNNYV0NVcN4wV0MaWMEO0iLuNGkseHuu5Snvp3YzZfXxDBWSLOUXc2zeXL2tA6So9WA5P3lZ/ga5i366EQ==

Orginal encrypted string after decrypt:

{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":9999999999},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}

Orginal decrypt function:

public static string Decypher(string var1)
    {
        var1 = var1.Trim();
        byte[] array = Convert.FromBase64String(var1);
        byte[] array2 = new byte[16];
        byte[] array3 = new byte[32];
        byte[] array4 = new byte[array.Length - 48];
        for (int i = 0; i < 16; i++)
        {
            array2[i] = array[i];
        }
        for (int j = 16; j < 48; j++)
        {
            array3[j - 16] = array[j];
        }
        for (int k = 48; k < array.Length; k++)
        {
            array4[k - 48] = array[k];
        }
        ivv = array2;
        Aes aes = Aes.Create();
        aes.Mode = CipherMode.CBC;
        aes.Key = GetToken();
        aes.IV = array2;
        MemoryStream memoryStream = new MemoryStream();
        ICryptoTransform transform = aes.CreateDecryptor();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
        string result = string.Empty;
        try
        {
            
            cryptoStream.Write(array4, 0, array4.Length);
            cryptoStream.FlushFinalBlock();
            byte[] array5 = memoryStream.ToArray();
            result = Encoding.ASCII.GetString(array5, 0, array5.Length);
            memoryStream.Close();
            cryptoStream.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.StackTrace);
        }
        return result;
    }

My encrypt function:

public void EncryptStringToBytes()
    {
        string plainText = textBox2.Text;
        byte[] array = Encoding.UTF8.GetBytes(plainText);
        byte[] encrypted;
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = GetToken();
            aesAlg.IV = new byte[16];
            aesAlg.Mode = CipherMode.CBC;
            var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        textBox3.Text = Convert.ToBase64String(encrypted);
    }

String after my encrypt & decrypt with orginal function:

?%j>]???r?????":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}

EDIT: Now encrypt function look:

public void EncryptStringToBytes()
    {
        string plainText = textBox2.Text.Trim();
        byte[] array = Encoding.ASCII.GetBytes(plainText);
        byte[] encrypted;
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = GetToken();
            aesAlg.IV = GetIV();
            aesAlg.Mode = CipherMode.CBC;
            var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            using (var msEncrypt = new MemoryStream())
            {
                msEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
                msEncrypt.Flush();
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    csEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        textBox3.Text = Convert.ToBase64String(encrypted);
    }

But string after encrypt & decrypt look:

;???En  Dp??g???{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}

Upvotes: 1

Views: 2865

Answers (1)

Joma
Joma

Reputation: 3869

My C# AES implementation

from my answer AES Crypto C# compatible Java

  • The IV is randomized in every Encrypt process to get different output with same text and avoid to intruders/attackers get original text easily.

  • The default mode is CBC.

  • The encoding used is UTF-8. UTF-8 is the most widely used encoding on the web.

You can test/run this code on https://replit.com/@JomaCorpFX/AesCbcEncrypt#main.cs

References

Block cipher mode of operation - IV
When using AES and CBC, is it necessary to keep the IV secret?
Initialization Vector - IV
Generate keys for encryption and decryption - Microsoft

Creating and managing keys is an important part of the cryptographic process. Symmetric algorithms require the creation of a key and an initialization vector (IV). You must keep this key secret from anyone who shouldn't decrypt your data. The IV doesn't have to be secret but should be changed for each session

The code

using System;
using System.Security.Cryptography;
using System.Text;

public enum HashAlgorithm
{
    MD5,
    SHA1,
    SHA256,
    SHA384,
    SHA512
}

public class HashManager
{
    public static byte[] ToRawHash(byte[] data, HashAlgorithm algorithm)
    {
        byte[] hash;
        switch (algorithm)
        {
            case HashAlgorithm.MD5:
                MD5 md5 = MD5.Create();
                hash = md5.ComputeHash(data, 0, data.Length);
                return hash;
            case HashAlgorithm.SHA1:
                SHA1Managed sha1 = new SHA1Managed();
                hash = sha1.ComputeHash(data);
                return hash;
            case HashAlgorithm.SHA256:
                SHA256Managed sha256 = new SHA256Managed();
                hash = sha256.ComputeHash(data);
                return hash;
            case HashAlgorithm.SHA384:
                SHA384Managed sha384 = new SHA384Managed();
                hash = sha384.ComputeHash(data);
                return hash;
            case HashAlgorithm.SHA512:
                SHA512Managed sha512 = new SHA512Managed();
                hash = sha512.ComputeHash(data, 0, data.Length);
                return hash;
            default:
                throw new ArgumentException("Invalid Algorithm");
        }
    }
}

public class AesManager
{
    private const int MAX_IV_LENGTH = 16;
    private const int MAX_KEY_LENGTH = 32;

    private static byte[] GenerateValidKey(byte[] keyBytes)
    {
        byte[] ret = new byte[MAX_KEY_LENGTH];
        byte[] hash = HashManager.ToRawHash(keyBytes, HashAlgorithm.SHA256);
        Array.Copy(hash, ret, MAX_KEY_LENGTH);
        return ret;
    }


    public static byte[] EncryptRaw(byte[] PlainBytes, byte[] Key)
    {
        AesManaged AesAlgorithm = new AesManaged()
        {
            Key = GenerateValidKey(Key)
        };
        AesAlgorithm.GenerateIV();
        var Encrypted = AesAlgorithm.CreateEncryptor().TransformFinalBlock(PlainBytes, 0, PlainBytes.Length);
        byte[] ret = new byte[Encrypted.Length + MAX_IV_LENGTH];
        Array.Copy(Encrypted, ret, Encrypted.Length);
        Array.Copy(AesAlgorithm.IV, 0, ret, ret.Length - MAX_IV_LENGTH, MAX_IV_LENGTH);
        return ret;
    }

    public static byte[] DecryptRaw(byte[] CipherBytes, byte[] Key)
    {
        AesManaged AesAlgorithm = new AesManaged()
        {
            Key = GenerateValidKey(Key)
        };
        byte[] IV = new byte[MAX_IV_LENGTH];
        Array.Copy(CipherBytes, CipherBytes.Length - MAX_IV_LENGTH, IV, 0, MAX_IV_LENGTH);
        AesAlgorithm.IV = IV;
        byte[] RealBytes = new byte[CipherBytes.Length - MAX_IV_LENGTH];
        Array.Copy(CipherBytes, RealBytes, CipherBytes.Length - MAX_IV_LENGTH);
        return AesAlgorithm.CreateDecryptor().TransformFinalBlock(RealBytes, 0, RealBytes.Length); ;
    }


    public static String EncryptToBase64(String Plaintext, String Key)
    {
        byte[] PlainBytes = Encoding.UTF8.GetBytes(Plaintext);
        return Base64Manager.ToBase64(EncryptRaw(PlainBytes, Encoding.UTF8.GetBytes(Key)), false);
    }



    public static String DecryptFromBase64(String CipherText, String Key)
    {
        byte[] CiPherBytes = Base64Manager.Base64ToByteArray(CipherText);
        byte[] Encrypted = DecryptRaw(CiPherBytes, Encoding.UTF8.GetBytes(Key));
        return Encoding.UTF8.GetString(Encrypted, 0, Encrypted.Length);
    }

}

public class Base64Manager
{
    public static byte[] Base64ToByteArray(String base64)
    {
        return Convert.FromBase64String(base64);
    }

    public static String ToBase64(byte[] data, Boolean insertLineBreaks = default(Boolean))
    {
        return insertLineBreaks ? Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks) : Convert.ToBase64String(data);
    }
}



public class Program
{
    public static void Main()
    {
        Console.Write("Plain text: ");
        string plainText = Console.ReadLine();
        Console.Write("Password: ");
        string password = Console.ReadLine();
        string encrypted = AesManager.EncryptToBase64(plainText, password);
        Console.WriteLine();

        Console.WriteLine($"Password: {password}" );
        Console.WriteLine();

        Console.WriteLine($"Encrypted: {encrypted}");
        Console.WriteLine();
        
        Console.WriteLine($"Decrypted: {AesManager.DecryptFromBase64(encrypted, password)}");
        Console.ReadLine();
    }
}

Output output

Upvotes: 1

Related Questions