Mcrypt_rijndael_128 Openssl

For MCRYPT you would define the key and cipher this way: 1. $key = ‘011120’; define(‘IVSIZE’, mcryptgetivsize(MCRYPTRIJNDAEL128, MCRYPTMODECBC)); For OPENSSL you would define the key the same way, and the cipher would be declared in the actual opensslencrypt function (shown later): 1. $iv = opensslrandompseudobytes(opensslcipherivlength(‘aes-256-cbc’)). Here is a solution based on this comment, using openssldecrypt from PHP. The JavaScript part (development with NodeJS for browsers) — first, install CryptoJS with npm install crypto-js, then your JS code.

Foreword: You probably should not be deploying your own cryptography to begin with, especially if you don't already understand that encryption is not authentication. For production systems, use PECL libsodium or defuse/php-encryption and save yourself the headache.

The rest of this post is intended for PHP developers who still want to write their own cryptography code, or already have.

I. Mcrypt is Abandonware

PHP's optional mcrypt extension provides bindings for a cryptography library called libmcrypt, which has been collecting dust since 2007 (eight years and counting) despite plenty of bugs, some which even have patches available.

If bit rot weren't enough reason to avoid using this library, the major design flaws which make it easier to write insecure code than it is to write secure code should.

II. It's Confusing and Counter-Intuitive

Look at this list of mcrypt ciphers and tell me how you would implement AES-256-CBC. If your code looks like this, you've just run headfirst into the first (and arguably most common) mcrypt design wart:

Surprise! MCRYPT_RIJNDAEL_256 doesn't mean AES-256.

All variants of AES use a 128-bit block size with varying key lengths (128, 192, or 256). This means that MCRYPT_RIJNDAEL_128 is the only correct choice if you want AES.

MCRYPT_RIJNDAEL_192 and MCRYPT_RIJNDAEL_256 instead refer to non-standard, less-studied variants of the Rijndael block cipher that operate on larger blocks.

Considering that AES-256 has much worse key scheduling than AES-128, it's not at all unreasonable to suspect there might be unknown weaknesses in the non-standard Rijndael variants that are not present in the standardized 128-bit block size version of the algorithm. At the very least, it makes interoperability with other encryption libraries that only implement AES a challenge.

Isn't it great that mcrypt makes you feel dumb for not knowing details that you probably shouldn't really need to know? Don't worry, it gets worse.

III. Null Padding

We already stated that not authenticating your ciphertexts is a bad idea, and in all fairness, padding oracle attacks are going to be a problem in CBC (Cipher Block Chaining) mode no matter what padding scheme you select if you fail to Encrypt then MAC.

If you encrypt your message with mcrypt_encrypt(), you have to choose between writing your own plaintext padding strategy or using the one mcrypt implements by default: zero-padding.

To see why zero-padding sucks, let's encrypt then decrypt a binary string in AES-128-CBC using mcrypt (The result of running this code is available here):

As you can see, padding a plaintext with zero bytes can lead to a loss of data. A much safer alternative is to use PKCS7 padding.

Here is an example of an unauthenticated AES-256-CBC encryption library written in Mcrypt with PKCS7 padding.

And here's the library written using OpenSSL.

In almost every metric, openssl wins over mcrypt:

  1. Specifying 'aes-256-cbc' is much more obvious than remembering to use MCRYPT_RIJNDAEL_128 with a 32-byte binary key.
  2. openssl_encrypt() performs PKCS7 padding by default, and lets you specify OPENSSL_ZERO_PADDING if you really want it.
  3. The code you write ends up much more compact and readable, with less room for implementation errors.
  4. It performs AES encryption/decryption much faster, since it supports AES-NI if your processor has this feature. AES-NI also means you don't have to worry about an attacker recovering your secret key from cache-timing information.
  5. OpenSSL is being actively developed and maintained. In response of the Heartbleed vulnerability last year, several organizations (including the Linux Foundation) declared the project critical Internet infrastructure and began pouring resources into finding and fixing bugs in the system. If you still don't trust it, there's always LibreSSL.

Simplicity, security, and performance. What more is there to ask for?

There are, however, two things with OpenSSL that you should watch out for.

OpenSSL Gotchas

  1. The CSPRNG they offer is a userspace PRNG based on hash functions, which goes against the advice of Thomas Ptacek to use /dev/urandom. The only one-liner alternative is mcrypt_create_iv(), as demonstrated above, but this function is only exposed if you enable the mcrypt extension. Fortunately, PHP 7 will offer a core random_bytes() function that leverages the kernel's CSPRNG.
  2. Although your version of OpenSSL might list GCM based cipher modes (e.g. aes-128-gcm), PHP doesn't actually support these methods yet.

Don't use mcrypt. If you're typing the word mcrypt into your code, you're probably making a mistake. Although it's possible to provide a relatively secure cryptography library that builds on top of mcrypt (the earlier version of defuse/php-encryption did), switching your code to openssl will provide better security, performance, maintainability, and portability.

Even better: use libsodium instead.


Mcrypt_rijndael_128 Openssl Library

Thu, 28 Mar 2019

Using openssl for AES-CBC-PKCS5Padding rather than mcrypt in PHP

Yeah, that’s quite an acronym soup.


Background: the mcrypt library for PHP has been deprecated for a long time now. However, in PHP we still have to process lots encrypted strings coming from a format like MCRYPT_RIJNDAEL_128 or stuff coming from Java (Android, I’m looking at you!), that was encrypted with a AES with Cipher Blocker Chaining and PKCS5Padding. These cipher algorithms are not explicitly included in openssl as such, although you can find stray references all over the web pointing you in the general direction.

I frequently have to integrate with third-party sites or services that are written in Java, and which provide sample PHP code for implementing my end. Because the ciphers in mcrypt are easier to identify, this provided source usually uses the deprecated library rather than openssl.


Mcrypt_rijndael_128 Openssl Private

So, to save some time, here’s the equivalent openssl encryption/decryption commands:

openssl_decrypt($encrypted, 'aes-128-cbc',$key, 0, $iv)

For a more verbose proof-of-concept, a longer test program is included below. But before you look at that, consider the following warnings:


Mcrypt_rijndael_128 openssl_encrypt
  1. Thank you very much for this code. I must changed by PHP Version from 7.1 to 7.2 and my code dosen’t work. I spended a lot of time to found this solution.

Mcrypt_rijndael_128 Openssl_encrypt

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Mcrypt_rijndael_128 Cbc Openssl