locked
Doing AES Encryption in C# RRS feed

  • Question

  • User-1204637165 posted

    There all I have a java software that I just built. I am trying to secure this software. The Java Desktop software communicates with Asp.net Core web api server.

    I have a java AES encryption that I am using to encrypt my license key for my java software to prevent people for cracking my encryption algorithm. My problem now is I need to translate that same encryption process for .NETCore. So what ever is encrypted in java can be deencrypted in Asp.net core c#.

    I have a code for c# AES encryption but I would paste it cos there is a part that gets me confused in it. The part of encryption keys in my java code, I dont know how to make it uniform to my c# code. I would paste both codes below.

    public class AES {
        
        private static SecretKeySpec secretKey;
        private static byte[] key;
     
        public static void setKey(String myKey)
        {
            MessageDigest sha = null;
            try {
                key = myKey.getBytes("UTF-8");
                sha = MessageDigest.getInstance("SHA-1");
                key = sha.digest(key);
                key = Arrays.copyOf(key, 16);
                secretKey = new SecretKeySpec(key, "AES");
            }
            catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
     
        public static String encrypt(String strToEncrypt, String secret)
        {
            try
            {
                setKey(secret);
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
            }
            catch (Exception e)
            {
                System.out.println("Error while encrypting: " + e.toString());
            }
            
            return null;
        }
    
        public static String decrypt(String strToDecrypt, String secret)
        {
            try
            {
                setKey(secret);
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
                cipher.init(Cipher.DECRYPT_MODE, secretKey);
                return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
            }
            catch (Exception e)
            {
                System.out.println("Error while decrypting: " + e.toString());
            }
            return null;
        }
        
    }

    MY C# code below

    class AESEncryption
        {
    
            static void EncryptAesManaged(string raw)
            {
                string test = "asdfasdf";
                
                try
                {
                    // Create Aes that generates a new key and initialization vector (IV).    
                    // Same key must be used in encryption and decryption    
                    using (AesManaged aes = new AesManaged())
                    {
                        // Encrypt string    
                        byte[] encrypted = Encrypt(raw, aes.Key, aes.IV);
                        // Print encrypted string    
                        Console.WriteLine($"Encrypted data: {System.Text.Encoding.UTF8.GetString(encrypted)}");
                        // Decrypt the bytes to a string.    
                        string decrypted = Decrypt(encrypted, aes.Key, aes.IV);
                        // Print decrypted string. It should be same as raw data    
                        Console.WriteLine($"Decrypted data: {decrypted}");
                    }
                }
                catch (Exception exp)
                {
                    Console.WriteLine(exp.Message);
                }
                Console.ReadKey();
            }
            static byte[] Encrypt(string plainText, byte[] Key, byte[] IV)
            {
                byte[] encrypted;
                // Create a new AesManaged.    
                using (AesManaged aes = new AesManaged())
                {
                    // Create encryptor    
                    ICryptoTransform encryptor = aes.CreateEncryptor(Key, IV);
                    // Create MemoryStream    
                    using (MemoryStream ms = new MemoryStream())
                    {
                        // Create crypto stream using the CryptoStream class. This class is the key to encryption    
                        // and encrypts and decrypts data from any given stream. In this case, we will pass a memory stream    
                        // to encrypt    
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            // Create StreamWriter and write data to a stream    
                            using (StreamWriter sw = new StreamWriter(cs))
                                sw.Write(plainText);
                            encrypted = ms.ToArray();
                        }
                    }
                }
                // Return encrypted data    
                return encrypted;
            }
            static string Decrypt(byte[] cipherText, byte[] Key, byte[] IV)
            {
                string plaintext = null;
                // Create AesManaged    
                using (AesManaged aes = new AesManaged())
                {
                    // Create a decryptor    
                    ICryptoTransform decryptor = aes.CreateDecryptor(Key, IV);
                    // Create the streams used for decryption.    
                    using (MemoryStream ms = new MemoryStream(cipherText))
                    {
                        // Create crypto stream    
                        using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                        {
                            // Read crypto stream    
                            using (StreamReader reader = new StreamReader(cs))
                                plaintext = reader.ReadToEnd();
                        }
                    }
                }
                return plaintext;
            }
    
    
    
        }

    So my confusion is how do I create an equivalent of

    setKey(String myKey)

    java method in c# so that both encryption would be the same

    Thursday, July 11, 2019 3:54 PM

Answers

  • User-1204637165 posted

    So I modified my c# code.  I would paste my modification. But the encrypted strings are still different. The java one seems to be perfect but c# gives me some funy lookin strings.

     class AESEncryption
        {
           static byte[] keybytes = new byte[16];
    
            public static void setSecretkeys(string keyvalue)
            {
    
                byte[] bytes = Encoding.Default.GetBytes(keyvalue);
                keyvalue = Encoding.UTF8.GetString(bytes);
    
                byte[] result;
                SHA1 shaM = new SHA1Managed();
                result = shaM.ComputeHash(bytes);                        
    
                Array.Copy(result, keybytes, 16);
    
                Console.WriteLine("This is the encryption key    " + Encoding.UTF8.GetString(keybytes));
            }
    
    
            public static string Encrypt(string plainText,string keyValue )//byte[] Key, byte[] IV
            {
                byte[] encrypted;
    
                setSecretkeys(keyValue);
    
                System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
                // Create a new AesManaged.    
                using (AesManaged aes = new AesManaged())
                {
                    aes.Key = keybytes; //UTF8.GetBytes(keyValue); 
                    aes.Mode = CipherMode.ECB;
                    aes.Padding = PaddingMode.PKCS7;
                    
    
                    // Create encryptor    
                    ICryptoTransform encryptor = aes.CreateEncryptor(); //Key, IV
                    // Create MemoryStream    
                    using (MemoryStream ms = new MemoryStream())
                    {
                        // Create crypto stream using the CryptoStream class. This class is the key to encryption    
                        // and encrypts and decrypts data from any given stream. In this case, we will pass a memory stream    
                        // to encrypt 
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            // Create StreamWriter and write data to a stream    
                            using (StreamWriter sw = new StreamWriter(cs))
                                sw.Write(plainText);
                            encrypted = ms.ToArray();
                        }
                    }
                }
    
                // Return encrypted data    
    
                return System.Text.Encoding.UTF8.GetString(encrypted);
              // return  ByteArrayToHexString(encrypted);
               // return encrypted;
            }
    }

    I more concerned at the encryption for now

    I would paste below string I used to test and the key so you all see .

    TEST VALUES BELOW

    String to encrypt:   first

    Encrypted string:   key

    JAVA OUTPUT

    ENCRYPTED RESULT BELOW

    Encrypted key    pi8iJb9wv6zLx/HvKjl4Ng==


    Encrypted string   jQsH/TZxvKKn2TPVfHaTqQ==

    C# OUTPUT

    Encryption key ?/"%?p??????*9x6

    Encrypted string ?[p]?6q????3?|v??

    It obvoius that the c# format is not same with the java format but I thought I have converted string to base64 why is it still showing like this. Please anyone help me.

    Thanks alot.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 12, 2019 7:27 AM
  • User753101303 posted

    For now you are missing the base64 encoding done on the Java side to show those binary values using printable characters.

    Add https://docs.microsoft.com/en-us/dotnet/api/system.convert.tobase64string?view=netframework-4.8 calls to show base64 strings as well. If it still doesn't match I'll give this a closer look. I don't find it right now but I discussed quite recently something similar and we ended up in finding the same values

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 12, 2019 7:40 AM

All replies

  • User753101303 posted

    Hi,

    From a seach it seems to compute a hash so it would be basically the same than https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.sha1managed?view=netframework-4.8

    Not sure if you can test a string and show maybe the base64 output you get so that one could try the same and see if it works.

    Thursday, July 11, 2019 5:09 PM
  • User-1204637165 posted

    thanks I would try it out

    Thursday, July 11, 2019 5:29 PM
  • User-1204637165 posted

    So I modified my c# code.  I would paste my modification. But the encrypted strings are still different. The java one seems to be perfect but c# gives me some funy lookin strings.

     class AESEncryption
        {
           static byte[] keybytes = new byte[16];
    
            public static void setSecretkeys(string keyvalue)
            {
    
                byte[] bytes = Encoding.Default.GetBytes(keyvalue);
                keyvalue = Encoding.UTF8.GetString(bytes);
    
                byte[] result;
                SHA1 shaM = new SHA1Managed();
                result = shaM.ComputeHash(bytes);                        
    
                Array.Copy(result, keybytes, 16);
    
                Console.WriteLine("This is the encryption key    " + Encoding.UTF8.GetString(keybytes));
            }
    
    
            public static string Encrypt(string plainText,string keyValue )//byte[] Key, byte[] IV
            {
                byte[] encrypted;
    
                setSecretkeys(keyValue);
    
                System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
                // Create a new AesManaged.    
                using (AesManaged aes = new AesManaged())
                {
                    aes.Key = keybytes; //UTF8.GetBytes(keyValue); 
                    aes.Mode = CipherMode.ECB;
                    aes.Padding = PaddingMode.PKCS7;
                    
    
                    // Create encryptor    
                    ICryptoTransform encryptor = aes.CreateEncryptor(); //Key, IV
                    // Create MemoryStream    
                    using (MemoryStream ms = new MemoryStream())
                    {
                        // Create crypto stream using the CryptoStream class. This class is the key to encryption    
                        // and encrypts and decrypts data from any given stream. In this case, we will pass a memory stream    
                        // to encrypt 
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            // Create StreamWriter and write data to a stream    
                            using (StreamWriter sw = new StreamWriter(cs))
                                sw.Write(plainText);
                            encrypted = ms.ToArray();
                        }
                    }
                }
    
                // Return encrypted data    
    
                return System.Text.Encoding.UTF8.GetString(encrypted);
              // return  ByteArrayToHexString(encrypted);
               // return encrypted;
            }
    }

    I more concerned at the encryption for now

    I would paste below string I used to test and the key so you all see .

    TEST VALUES BELOW

    String to encrypt:   first

    Encrypted string:   key

    JAVA OUTPUT

    ENCRYPTED RESULT BELOW

    Encrypted key    pi8iJb9wv6zLx/HvKjl4Ng==


    Encrypted string   jQsH/TZxvKKn2TPVfHaTqQ==

    C# OUTPUT

    Encryption key ?/"%?p??????*9x6

    Encrypted string ?[p]?6q????3?|v??

    It obvoius that the c# format is not same with the java format but I thought I have converted string to base64 why is it still showing like this. Please anyone help me.

    Thanks alot.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 12, 2019 7:27 AM
  • User753101303 posted

    For now you are missing the base64 encoding done on the Java side to show those binary values using printable characters.

    Add https://docs.microsoft.com/en-us/dotnet/api/system.convert.tobase64string?view=netframework-4.8 calls to show base64 strings as well. If it still doesn't match I'll give this a closer look. I don't find it right now but I discussed quite recently something similar and we ended up in finding the same values

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 12, 2019 7:40 AM
  • User-1204637165 posted

    Dear Pat,

    Thanks alot. you are the best. Immediately I added the Base64 encoding. it worked like magic. the ecryption is exactly the same boss.

    Thanks alot.

    Friday, July 12, 2019 8:34 AM