2

I'm a noob developer and I'm trying to decrypt some data but when I use OpenSSL in PHP I received no response. Also, when trying to encrypt data OpenSSL add a block of characters.

This is the code:

    <?php
    $dataToDecrypt = hex2bin("C2E5CDFE8BBFBC7350D40538434824DD3E11520B89A5BFDE24FA064DB2EED6EA");
    $aesKey = hex2bin("E3FB8EA130722FA99266B96B77C2735C39393939393939393920202020202020");
    $iv = hex2bin("00000000000000000000000000000000");
    $result = openssl_decrypt($dataToDecrypt, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
    echo bin2hex($result);
?>

The $result is supposed to be:

C3A6149C73FFBE4EAD36DC62FE40877D17CD690F37B06058CA3D65A345CC8212

I've tried this on VB and even in a AES encription web page (http://aes.online-domain-tools.com/) and the result is correct. But when trying with PHP I've got no answer.

I noticed when encrypting with the same information, the encrypted data is different. This is the code:

    <?php
    $dataToEncrypt = hex2bin("C3A6149C73FFBE4EAD36DC62FE40877D17CD690F37B06058CA3D65A345CC8212");
    $aesKey = hex2bin("E3FB8EA130722FA99266B96B77C2735C39393939393939393920202020202020");
    $iv = hex2bin("00000000000000000000000000000000");
    $result = openssl_encrypt($dataToEncrypt, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
    echo bin2hex($result);
?>

When I encrypt the result is:

C2E5CDFE8BBFBC7350D40538434824DD3E11520B89A5BFDE24FA064DB2EED6EA3A3ED407DC78D6AF9030BAB90CB40EAD

I get 32 characters more than expected (3A3ED407DC78D6AF9030BAB90CB40EAD). When I encrypt in VB or using the web page mentioned before I don't get these 32 extra characters.

Why is this happening? Am I missing something? I've been searching for an answer for several days. Any help is appreciated.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • 1
    You can use backticks: \` instead of single quotes to highlight inline code. Your English is fine, but I'd recommend using uppercase for names such as OpenSSL and PHP to make your question look more professional. You can click [this](https://stackoverflow.com/posts/44140853/revisions) to see my changes. – Maarten Bodewes May 23 '17 at 17:37

1 Answers1

2

To see something during PHP decrypt you need to turn on warning messages.

Essentially the openssl_decrypt call will first decrypt your ciphertext. As long as your ciphertext is a multiple of 16 bytes (the block size of AES) this will always succeed. After that it will try and perform PKCS#7 compatible unpadding, which will fail (with high probability). To make it not unpad, use the OPENSSL_ZERO_PADDING in addition to OPENSSL_RAW_DATA.

The same goes for your encryption function of course. Currently you receive the ciphertext of the padded plaintext. This will add exactly one block of padding if the input plaintext is a multiple of the block size (and it is in your sample code). So you need OPENSSL_ZERO_PADDING there as well.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Haven't tested it so please let me know if solves your problem. – Maarten Bodewes May 23 '17 at 17:33
  • 1
    Just to clarify, you can use `3` (as `$options`) to enable both `OPENSSL_ZERO_PADDING` and `OPENSSL_RAW_DATA` (which indeed produces the correct output). – Tom Udding May 23 '17 at 17:37
  • Glad it worked, and welcome to StackOverflow of course :) By the way, could you do me a favor and check if encrypt works for a ciphertext of e.g. 31 bytes instead of 32 bytes as you are trying now? I'm wondering if OPENSSL_ZERO_PADDING is actually zero padding (padding with zeros) or no padding (in which case the option would be very badly named). – Maarten Bodewes May 23 '17 at 18:15
  • @JocelynGonzálezVanHorne OK, a very bad name for an option in that case, thank you for trying that out for me! If you need a constant name for the value of 3, you could use `OPENSSL_RAW_NO_PADDING`. – Maarten Bodewes May 23 '17 at 18:39
  • Damn, I was scratching my head foe many hours over this - adding `OPENSSL_ZERO_PADDING` solved the thing! Thank you, my friend! – Jay Dadhania Jan 24 '21 at 04:15