2

I have a project involving a client encrypting data with AES-256 using the OpenSSL library and then passing it to a web server where it's decrypted and put into a database. I started out using Mcrypt on the PHP side since it's better-documented. I quickly found that I had a DB full of garbage data. I put together a little script that illustrates the problem:

<?php

header("Content-Type: text/plain; charset=utf-8");

$originalText = "The quick brown fox jumped over the lazy dog.";

$aesKey = pack('H*', "503592474D07C14B1997FB690A981F5DBF7D10A95C812D9F0A5F62B551B89970");
$aesIV = pack('H*', "FF964346DB1F2A65B19E67F4F3CA032E");

$cipherText = openssl_encrypt($originalText, "AES-256-OFB", $aesKey, 0, $aesIV);

$plainText = mcrypt_decrypt("rijndael-128", $aesKey, $cipherText, "ofb", $aesIV);
echo $plainText;

?>

Theoretically, this should simply return the original text, but instead I get a garbage string.

I!��/����m�y`Ac��_ UE0o�8*��*B"<[�߲�NM�ʚ�:ľH��|

I was able to work around the problem for now by using openssl_decrypt(), but I'd still like to know what's wrong with the original code. Aren't different AES implementations supposed to be interoperable?

DarkMorford
  • 495
  • 1
  • 3
  • 11
  • 1
    You are using in one place AES-256-OFB and in another rijndael-128, why would they be compatible? One is 256 bit, the other is 128bit – Noam Rathaus Jan 16 '14 at 07:23
  • Just to add to nrathaus comment. AES-128 and rijndael-128 are compatible, but AES-256 and rijndael-256 are not. – Syon Jan 16 '14 at 14:11
  • The 256 in AES-256-OFB is referring to the key size. The 128 in rijndael-128 is referring to the block size. rijndael has a variable block size (unlike AES) so it needs it to be specified. – neubert Jan 16 '14 at 16:05
  • 1
    Actually, despite the different notation, I found a number of sources (including Mcrypt's site) that say it's correct. AES always uses a 128-bit block size, and the number indicates the size of the secret key. On the other hand, Mcrypt's Rijndael implementation supports different block sizes—specified in the algorithm string—and infers the key size from what it's given. So whether you want AES-128, -192, or -256, Rijndael-128 is supposed to be correct. (For the record, I tried Rijndael-256 and it didn't make things any better.) – DarkMorford Jan 16 '14 at 16:13
  • Also see [Upgrading my encryption library from Mcrypt to OpenSSL](http://stackoverflow.com/q/43329513/608639) and [Preparing for removal of Mcrypt in PHP 7.2](http://stackoverflow.com/q/42696657/608639) – jww Apr 21 '17 at 17:48

1 Answers1

1

My guess: you need to be doing 'nofb' instead of 'ofb'. See https://bugs.php.net/bug.php?id=51146 .

neubert
  • 14,208
  • 21
  • 90
  • 172
  • That's it exactly. Fixed the sample code and it worked in my project code, too. Thanks! (Although now I'm wondering why they were using an 8-bit feedback cycle in the first place...) – DarkMorford Jan 17 '14 at 01:21