0

I have a string encrypted with AES 128 CBC, which I need to decrypt. I have the key which seems to work fine. The problem is with the initialization vector (IV).

The IV is 16 bytes long,

B409678003171307B8B8B8B8B8B8B8B8

but when I add it to my script, OpenSSL truncates it saying it's 32 long like so:

openssl_decrypt(): IV passed is 32 bytes long which is longer than the 16 expected by selected cipher, truncating

I guess it means it is 32 characters long - but how do I make it understand it's just 16 bytes?

UPDATE: using hex2bin on the IV solved the truncating - but my openssl_decrypt yields nothing. Also did the hex2bin on the key, still no output. Simplified the code to make it easier to find the problem:

<?php
$str = "7F53B967F1BF7C9EC26B0C405E453ABD";
$k = "F71D4590A6E6E219EBBE8BFE9D3DC21A";
$intv = "B409678003171307B8B8B8B8B8B8B8B8";
$key = hex2bin($k);
$iv = hex2bin($intv);
$plaintext = openssl_decrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
print_r($plaintext);
?>

So, is the hex2bin the wrong way to go? Or is there something wrong in how I use the openssl_decrypt? There are NO errors in the PHP error_log.

Thanks in advance!

jww
  • 97,681
  • 90
  • 411
  • 885
Mikkel
  • 43
  • 7
  • 2
    It's 32 hex characters, you need to hex-decode it to make 16 true eight-bit bytes. I don't know PHP so I can't tell you how. Maybe a hex2bin function. – President James K. Polk Mar 14 '17 at 13:00
  • Thanks, tried it out. It stops the truncating, but it doesn't seem to decrypt anything - $plaintext comes out empty. Anyone else? – Mikkel Mar 14 '17 at 13:13
  • any errors in your PHP error log? – Martin Mar 14 '17 at 13:23
  • Nope, not after adding the hex2bin. But the output is still empty. Using a webbased decryption tool, the supplied parameters decrypt perfectly, so something must be wrong with how I am using OpenSSL_decrypt. – Mikkel Mar 14 '17 at 13:33
  • print out your variables before applying them to the function, `print_r($input);` is this data the shape you expect? – Martin Mar 14 '17 at 13:40
  • In general, yes it is. The only thing that's a bother is the IV which is now illegible - "´ g€¸¸¸¸¸¸¸¸" but I suppose that is to be expected after the hex2bin. – Mikkel Mar 14 '17 at 13:51
  • have you turned the key into a `binary` value? – Martin Mar 14 '17 at 14:20
  • Hi Martin, yeah to no avail. It yields no output regardless. Is it correct to use the hex2bin here or is that the issue? – Mikkel Mar 14 '17 at 14:31
  • @Mikkel it depends if the key value `$k` is a hex value? Alternatively you can use `string2bin` [here](http://stackoverflow.com/questions/6382738/convert-string-to-binary-then-back-again-using-php) – Martin Mar 14 '17 at 14:39
  • Can you link the web-based encryption tool? It would be helpful to compare. – S. Imp Mar 14 '17 at 14:50
  • http://extranet.cryptomathic.com/aescalc/index?key=F71D4590A6E6E219EBBE8BFE9D3DC21A&iv=B409678003171307B8B8B8B8B8B8B8B8&input=7F53B967F1BF7C9EC26B0C405E453ABD&mode=cbc&action=Decrypt&output=CBDD1044213AD1016A6837C474E40CB1 – Mikkel Mar 14 '17 at 14:53
  • @Martin have to admit I couldn't get the string2bin concept to work - but is it really necessary? What a serious lack of documentation on OpenSSL. – Mikkel Mar 14 '17 at 15:02

1 Answers1

2

OK this appears to achieve the same results as the web-based service linked by the OP. The key steps are a) in addition to $k and $intv, make sure you also convert the encrypted $str to binary from its hex representation b) supply the extra flag OPENSSL_ZERO_PADDING c) when you echo or var_dump or print_r the output, make sure you do a conversion back to hex so the output is readable

$encrypted = "7F53B967F1BF7C9EC26B0C405E453ABD";
$k = "F71D4590A6E6E219EBBE8BFE9D3DC21A";
$intv = "B409678003171307B8B8B8B8B8B8B8B8";
$str = hex2bin($encrypted);
$key = hex2bin($k);
$iv = hex2bin($intv);

$decrypted = openssl_decrypt($str, 'AES-128-CBC', $key,  OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
$str_decrypted = bin2hex($decrypted);
var_dump($str_decrypted);

output:

string(32) "2f2f0c1335000000046d372b27230f15"

NOTE: I can't be sure that this is in fact the decrypted form of the originally encrypted data. It just matches the web-based service. I'm assuming the value you linked is in fact the correct value. Simply adding the OPENSSL_ZERO_PADDING flag to your original code can get rid of the errors but the output will be different. Maybe try some experimenting.

S. Imp
  • 2,833
  • 11
  • 24
  • 1
    @Mikkel glad to hear that. Can't stress enough that I'm just trying to mirror the result from that site you linked -- my answer is not based on some profound knowledge of openssl_decrypt. – S. Imp Mar 14 '17 at 15:15