PHP gives the error: mcrypt_encrypt(): The IV parameter must be as long as the blocksize

What he does not like in the vector?

 // Ключ $AES_Key = "93908027539382757893442837120983"; // Вектор $AES_IV = "33985771209830270358974938292834"; // Методы function encrypt($string) { return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $AES_Key, addpadding($string), MCRYPT_MODE_CBC, $AES_IV)); } function addpadding($string, $blocksize = 32) { $len = strlen($string); $pad = $blocksize - ($len % $blocksize); $string .= str_repeat(chr($pad), $pad); return $string; } 

Similar code on sharpe works fine:

 // Ключ private const string AES_Key = "93908027539382757893442837120983"; // Вектор private const string AES_IV = "33985771209830270358974938292834"; // Зашифровывает строку в AES CBC 256 PKCS7 internal static string AES_Encrypt(string inputStr) { byte[] xBuff = null; using (var aes = new RijndaelManaged()) { // Настройки aes.KeySize = 256; aes.BlockSize = 256; aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; aes.Key = Encoding.UTF8.GetBytes(AES_Key); aes.IV = Encoding.UTF8.GetBytes(AES_IV); using (var ms = new MemoryStream()) { using (var cs = new CryptoStream(ms, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write)) { byte[] textArr = Encoding.UTF8.GetBytes(inputStr); cs.Write(textArr, 0, textArr.Length); } xBuff = ms.ToArray(); } } return Convert.ToBase64String(xBuff); } 
  • I would venture to suggest that he does not like the length of IV: you have a string of 32 bytes in length, and the block length for AES is only 16 bytes. Why and how exactly (!) It works in C # - the devil knows it. Perhaps the line is cut to block size - Vladimir Martyanov
  • @ Vladimir $iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND); echo mb_strlen ($iv); , a simple piece of code says that you are wrong: $iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND); echo mb_strlen ($iv); $iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND); echo mb_strlen ($iv); == 32 characters \ byte. With the vector generated by PHP - no problem. Note that a 256 bit key is used, the vector length must be 32*8=256 бит . - Alexis
  • What kind of entertainers they are, it’s even interesting what they do with the extra 16 bytes IV in the CBC ... - Vladimir Martyanov
  • The length of IV does not depend on the key length for AES, since the block length for AES is always (!!!) 16 bytes or 128 bits. - Vladimir Martyanov
  • @ Vladimir Martiyanov, set the vector of 16 digits - nothing has changed. The same mistake. - Alexis

1 answer 1

Working option:

PHP:

 // Методы function encrypt($message) { // Ключ $AES_Key256 = '28937539283712098445739080393827'; // Вектор $AES_IV = '8574930392882739'; // Алгоритм шифрования $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); if (mcrypt_generic_init($cipher, $AES_Key256, $AES_IV) != -1) { $cipherText = mcrypt_generic($cipher, addpadding($message)); mcrypt_generic_deinit($cipher); return base64_encode($cipherText); } } function addpadding($string, $blocksize = 16) { $len = strlen($string); $pad = $blocksize - ($len % $blocksize); $string .= str_repeat(chr($pad), $pad); return $string; } 

C #

 // Ключ private const string AES_Key = "28937539283712098445739080393827"; // Вектор private const string AES_IV = "8574930392882739"; // Расшифровывает строку из AES 256 CBC PKCS7 из файла internal static string AES_Decrypt(string inputStr) { byte[] xBuff = null; using (var aes = new RijndaelManaged()) { // Настройки aes.KeySize = 256; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.Key = Encoding.UTF8.GetBytes(AES_Key); aes.IV = Encoding.UTF8.GetBytes(AES_IV); using (var ms = new MemoryStream()) { using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write)) { byte[] textArr = Convert.FromBase64String(inputStr); cs.Write(textArr, 0, textArr.Length); } xBuff = ms.ToArray(); } } return Encoding.UTF8.GetString(xBuff); } 

An article necessary to understand how AES works in PHP: https://www.chilkatsoft.com/p/php_aes.asp

  • What was the problem? - Vladimir Martyanov
  • @ Vladimir Martianov, there were several problems. The first is that fields in PHP were out of sight of the method. The second is that in PHP the parameter of the method MCRYPT_RIJNDAEL_256 meant not the key length, but the length of the block, and the key length is specified by the length of the key parameter. What in my opinion is extremely "wrong" (and this is an understatement). Thirdly, the difference between the AES and Rijndael protocol. According to the article, in order to be AES compatible, you should use only MCRYPT_RIJNDAEL_128 in PHP, respectively, I altered the length of the block in C # just like the other parameters (length IV, etc.) - Alexis
  • @ Vladimir Martianov, and yes, you were right about the block length in AES, but not right about the block length in Rijndael. Rijndael supports a large block length, while AES supports only 128 bits. So if you go back to your question about where the second 16 characters \ bytes are relative to C #, they are used because Rijndael supports them, unlike AES. In PHP, all the awesome things ... - Alexis