-1

we have java library which will do encryption and decryption using AES with Password, which we need to port to .NET.

Here is my java code -

import java.util.*;
import java.lang.*;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

class Rextester
{  
    public static void main(String args[])
    {
        byte[] encrypted = EncryptonToBytes("Hello");
        System.out.println("Encrypted: " + encrypted); // Result --> Encrypted: [B@1c53fd30
        String decrypted = DecryptionFromBytes(encrypted);
        System.out.println("Decrypted: " + decrypted);
    }

    public static final byte[] EncryptonToBytes(String str)
    {
        byte[] result = null; 

        //Create SecretKey object from common secret key string mentioned in constants class
        byte[] encoded = new BigInteger("728faf34b64cd55c8d1d500268026ffb", 16).toByteArray();
        SecretKey secretKey = new SecretKeySpec(encoded, "AES");

        Cipher cipher;
        try {
            //Cipher class object using AES as transformation
            cipher = Cipher.getInstance("AES");

            //Initialize cipher in encrypt mode along with secret key object created above.
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);

            //Encrypt input string
            result = cipher.doFinal(str.getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        } 

        //Return null in case of any error
        return result;
    }

    public static String DecryptionFromBytes(byte[] base64Data) 
    {       
        try {
            //Create SecretKey object from common secret key string mentioned in constants class
            byte[] encoded = new BigInteger("728faf34b64cd55c8d1d500268026ffb", 16).toByteArray();
            SecretKey secretKey = new SecretKeySpec(encoded, "AES");

            //Cipher class object using AES as transformation
            Cipher cipher = Cipher.getInstance("AES");

            //Initialize cipher in decrypt mode along with secret key object created above.
            cipher.init(Cipher.DECRYPT_MODE, secretKey);

            //Decrypt input byte array
            byte[] decryptedByte = cipher.doFinal(base64Data);

            //return decrypted input bytes as string
            return (new String(decryptedByte));
        } catch (Exception e) {
            e.printStackTrace();
        } 

        //return empty string if any error 
        return "";
    }
}

I followed some of the articles below -

  1. Using AES encryption in C#
  2. http://csharphelper.com/blog/2014/09/encrypt-or-decrypt-files-in-c/
  3. https://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt
  4. Cipher, Java encrypt, C# decrypt
  5. Password encryption/decryption code in .NET
  6. https://ourcodeworld.com/articles/read/471/how-to-encrypt-and-decrypt-files-using-the-aes-encryption-algorithm-in-c-sharp
  7. http://mjremijan.blogspot.com/2014/08/aes-encryption-between-java-and-c.html

But none of them gave me desired output. What I'm looking for is - both my java and .net functions should give me same result. From last one week I'm trying to get it done, totally frustrated. Your help will be much appreciated.

1 Answers1

0

The two methods:

public static byte[] EncryptionToBytes(string str)
{
    using (var aes = new AesManaged())
    {
        aes.Key = new byte[] { 0x72, 0x8f, 0xaf, 0x34, 0xb6, 0x4c, 0xd5, 0x5c, 0x8d, 0x1d, 0x50, 0x02, 0x68, 0x02, 0x6f, 0xfb };
        aes.Mode = CipherMode.ECB;
        aes.Padding = PaddingMode.PKCS7;

        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] data = Encoding.UTF8.GetBytes(str);
                cs.Write(data, 0, data.Length);
            }

            byte[] encrypted = ms.ToArray();
            return encrypted;
        }
    }
}

public static string DecryptionFromBytes(byte[] encrypted)
{
    using (var aes = new AesManaged())
    {
        aes.Key = new byte[] { 0x72, 0x8f, 0xaf, 0x34, 0xb6, 0x4c, 0xd5, 0x5c, 0x8d, 0x1d, 0x50, 0x02, 0x68, 0x02, 0x6f, 0xfb };
        aes.Mode = CipherMode.ECB;
        aes.Padding = PaddingMode.PKCS7;

        using (var ms2 = new MemoryStream())
        {
            using (var ms = new MemoryStream(encrypted))
            using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read))
            {
                cs.CopyTo(ms2);
            }

            byte[] decrypted = ms2.ToArray();
            return Encoding.UTF8.GetString(decrypted);
        }
    }
}

Note that

System.out.println("Encrypted: " + encrypted);

won't print the byte[], but will print [, followed by a character representing the type of the array's elements (in your case C for char), followed by @ then the "identity hash code" of the array (think of it like you would a "memory address").

Java seems to use (haven't looked for documentation) AES with mode ECB, padding PKCS7 (this confirms my observation)

Note that String.getBytes() encodes using the "default" encoding, that could be different in different computers. Better to use getBytes("UTF-8") and new String(bytes, "UTF-8") (see https://stackoverflow.com/a/5729823/613130). In the code I wrote I used UTF8. You can simulate the Java code by using Encoding.Default.

xanatos
  • 109,618
  • 12
  • 197
  • 280