0

I need to decrypt a string as part of an authorization process.

The documentation specifies that the authorization string was encrypted with the following settings:

  • Padding of input data: PKCS*7
  • Password byte array is 32 bytes long. Password string is converted to UTF-16 encoded byte array and byte array is then padded with zeroes up to length of 32 bytes. Longer passwords are truncated.

The C# example:

 /// <summary> /// Decrypts a string. /// </summary> /// <param name="content">The string to decrypt.</param> /// <param name="password">The password to use.</param> /// <returns>The decrypted string.</returns> private static string DecryptString(string content, string password) { Rijndael aes; byte[] retVal = null; byte[] contentBytes; byte[] passwordBytes; byte[] ivBytes; try { contentBytes = Convert.FromBase64String(content); //Create the password and initial vector bytes passwordBytes = new byte[32]; ivBytes = new byte[16]; Array.Copy(Encoding.Unicode.GetBytes(password), passwordBytes, Encoding.Unicode.GetBytes(password).Length); Array.Copy(passwordBytes, ivBytes, 16); //Create the cryptograpy object using (aes = Rijndael.Create()) { aes.Key = passwordBytes; aes.IV = ivBytes; aes.Padding = PaddingMode.PKCS7; //Decrypt retVal = aes.CreateDecryptor().TransformFinalBlock(contentBytes, 0, contentBytes.Length); } } catch { } return Encoding.Unicode.GetString(retVal); } 

The same function was discussed here, but for JAVA: Decrypt C# RIJNDAEL encoded text

I tried to decrypt it with the following function but the result is different than expected:

function decrypt($string, $pass){ $iv = substr($pass, 0, 16); $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $pass, base64_decode($string), MCRYPT_MODE_CBC, $iv); $pad = ord($data[strlen($data) - 1]); return substr($data, 0, -$pad); } 

The ecrypted string "7iTdZnp0DtGnIfwwqY4W/glbLLVZ0+asVLAuz13PzrW0wM6HC7rNuQvcG8JDSehyYeBJARdXHgLo9hRL9sBz3fN5LJ8cro3o0kFnAao2YRU="

should decrypt to

"ldYWMFlSbcki6LMl3rkNfGavnt8VqmZd" 

using the password "GAT"

I think it has something to do with the password / iv / encoding

9
  • You aren't showing how you encode the $pass :-) Commented Apr 22, 2015 at 10:17
  • But I can confirm that the block mode is CBC, so MCRYPT_MODE_CBC is right. Commented Apr 22, 2015 at 10:19
  • This is the part i don't get: Password string is converted to UTF-16 encoded byte array and byte array is then padded with zeroes up to length of 32 bytes. For mcrypt_decrypt, for the key the php manual explains that - If it's smaller than the required keysize, it is padded with '\0'. How should I encode the password before using it in mcrypt_decrypt? Commented Apr 22, 2015 at 11:08
  • You only need to do the Encoding to UTF16 and if necessary the cut to 32 bytes Commented Apr 22, 2015 at 11:13
  • Already tried that: $password = mb_convert_encoding('GAT', 'utf-16le'); Commented Apr 22, 2015 at 11:24

1 Answer 1

0
function decrypt($string, $pass) { $encodedPass = mb_convert_encoding($pass, 'utf-16le'); $encodedPass = substr($encodedPass, 0, 32); $encodedPass = str_pad($encodedPass, 32, "\0", STR_PAD_RIGHT); $iv = substr($encodedPass, 0, 16); $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $encodedPass, base64_decode($string), MCRYPT_MODE_CBC, $iv); $pad = ord($data[strlen($data) - 1]); return substr($data, 0, -$pad); } 

In PHP, the MCRYPT_RIJNDAEL_128/MCRYPT_RIJNDAEL_256 isn't the size of the key, but the size of the block (see https://www.chilkatsoft.com/p/php_aes.asp). C# normally uses 16 bytes blocks, so MCRYPT_RIJNDAEL_128. The size of the key is auto-detected. Note that I've moved the encoding/resizing of the password inside the method.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.