2

I have been requested to encrypt some data while talking to my partner's JAVA API, and he sent me the following details about encryption algorithm:

  • Algorithm : AES256
  • Key Size : 256 bits
  • Encryption Mode: CBC (16 bits blocks, PKCS5Padding with 0)
  • Output Type : Base-64
  • Password: 0xA8703827AE586460105696504327B7BB0806FEAE96BD664F89E36868FBB48E3D
  • IV: is a byte[16] with 0 values

I used the below code, but I didn't get a matched result with him:

public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
    byte[] encryptedBytes = null;
    byte[] saltBytes = new byte[16] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    using (MemoryStream ms = new MemoryStream())
    {
        using (RijndaelManaged aes = new RijndaelManaged())
        {
            aes.KeySize = 256;
            aes.BlockSize = 128;

            var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
            aes.Key = key.GetBytes(aes.KeySize / 8);
            aes.IV = key.GetBytes(aes.BlockSize / 8);
            aes.Padding = PaddingMode.PKCS7;

            aes.Mode = CipherMode.CBC;

            using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                cs.Close();
            }
            encryptedBytes = ms.ToArray();
        }
    }

    return encryptedBytes;
}


public string EncryptText(string input, string password)
{
    byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
    byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

    passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

    byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

    string result = Convert.ToBase64String(bytesEncrypted);

    return result;
}

So, when we tried to encrypt Hello, How are you?, I got a different result and I should get the same result he had as he will decrypt my sent data on his side and will process it. The given example should have this result: TJTojNoVgoqnhCj4uTv1jLBiZU7r+s/0Bm234bHU+S0=

Ahmed Negm
  • 865
  • 1
  • 11
  • 30
  • 3
    You would need to supply the java code in order to figure out why they don't agree. – President James K. Polk Aug 02 '17 at 13:38
  • The client referred to [this](https://dzone.com/articles/aes-256-encryption-java-and), if you couldn't find this enough, kindly let me know to ask him for further information – Ahmed Negm Aug 02 '17 at 13:39
  • 1
    As you can plainly see yourself this are vast differences between your code and that code, particularly in the derivation of the key and IV. – President James K. Polk Aug 02 '17 at 13:44
  • @JamesKPolk, okay, but actually, I couldn't fix it, I am not professional with these stuffs, so, it would be great if you can guide me through that. – Ahmed Negm Aug 02 '17 at 13:46
  • 1
    You need to ask about [IV](https://en.wikipedia.org/wiki/Initialization_vector) - What is the IV used in their code ? Is it included as part of the result cipher text ? Similarly for Key, as James has pointed out in the comment above, the logic of Key and IV MUST match exactly. Do post the full Java code as well and you can try to match the logic. Also look at this [SO post](https://stackoverflow.com/questions/21890805/encrypt-aes-with-c-sharp-to-match-java-encryption) as well – Subbu Aug 02 '17 at 15:10
  • IV = 0 ... but I don't know how can I configure that in my code – Ahmed Negm Aug 02 '17 at 16:21
  • @Subbu, I returned back to them asking for the same, and they provided me with this [link](https://dzone.com/articles/aes-256-encryption-java-and), and they told me that this link matches the same logic they working with. On the other hand, IV is a byte[16] of 0 values. – Ahmed Negm Aug 03 '17 at 07:37

1 Answers1

2

I did some testing and now able to match your expected result.

2 changes to be done.

IV

IV is the easiest, as you said IV = 0, so set IV as follows:

aes.IV = new byte[16];

In AES, IV is 16 bytes. The above would create a byte array of 16 bytes with each value initialized to zero.

Key

The password you have given starts with "0x" - this essentially means that this is hexadecimal representation of the password string. I converted this password to byte array using this

string password = "A8703827AE586460105696504327B7BB0806FEAE96BD664F89E36868FBB48E3D";

Please note I removed the starting "0x" from the above

byte[] passwordBytes = StringToByteArray(password);

The above converts the hexadecimal password representation to a byte array.

In your AES_Encrypt method, directly assign this byte[] as the Key

aes.Key = passwordBytes;

Now, my result is TJTojNoVgoqnhCj4uTv1jLBiZU7r+s/0Bm234bHU+S0= which exactly matches with your expected output.

Subbu
  • 2,130
  • 1
  • 19
  • 28
  • Thanks Subbu for your kind help, but I didn't get the same result after the modifications you have mentioned. You can find the new code after modification available for download [here](https://www.dropbox.com/s/m9f7jqiauk5ne0h/Class1.cs?dl=0). I really appreciate your support. – Ahmed Negm Aug 03 '17 at 16:43
  • 1
    remove this line from your code `passwordBytes = SHA256.Create().ComputeHash(passwordBytes);` – Subbu Aug 03 '17 at 16:49
  • WOW! it works correctly now, I will contact them next week to make sure that everything works fine. On the other hand, many thanks Subbu for your kind help, I really appreciate that. – Ahmed Negm Aug 03 '17 at 16:57