## Strong cryptography in PHP

If you are a professional web developer, security is an important aspect of your job. If you are planning to store some critical or sensitive data in your web application, like passwords, credit cards, etc, you should use** strong cryptography **to protect the data.

**What is strong cryptography?**

Strong cryptography is the usage of systems or components that are considered highly resistant to cryptoanalysis, the science of cracking codes.

Theoretically speaking, if we encrypt and store sensitive data in a database or file, a malicious attacker will not be able to decrypt it without prior knowledge of the key, a sequence of elements used to encrypt or decrypt data.

How can we prove that an attacker will not be able to decrypt the data? Unfortunately, the correct answer is that we cannot be sure. We can only obtain a good level of security using well tested algorithms of cryptography (strong cryptography).

By way of an example, the ENIGMA cipher, used in the second world war was a system to encrypt the communication between german soldiers. It is not considered cryptographically strong today.

The DES, a FIST standard algorithm in 1976 that, unfortunately, is still used in many systems, is not considered strong cryptography anymore. In 1998 the Electronic Frontier Foundation (EFF) built a machine, the EFF DES cracker, to perform a brute force search of DES cipher’s key space — that is, to decrypt an encrypted message by trying every possible key. The aim in doing this was to prove that DES’s key is not long enough to be secure. This machine was able to find the key of an encrypted message in less than 1 day and bear in mind this was 1998.

Currently, some of the algorithms that can be considered cryptographically strong are: Blowfish, Twofish, Advanced Encryption Standard (AES, Rijndael), 3DES, Serpent, RSA, etc. It is important to say that the security of an algorithm is related to the strength and the size of the key.

**Why should we use strong cryptography?**

Many developers, try to implement their personal cipher using different approaches. On the internet, you can find many implementations of homemade ciphers in PHP. We strongly discourage the use of these homemade ciphers. Creating a secure cipher is very complex undertaking which can only be completed by an expert.In addition to this, the testing phase of the design of the cipher will require some time to prove it is secure.

**Strong cryptography in PHP**

PHP offers different implementations of the most important cryptographic algorithms. In particular PHP has the following cryptographic extensions:

**Hash****mcrypt****OpenSSL**

The **Hash** extension requires no external libraries and is enabled by default as of PHP 5.1.2. This extension replaces the old mhash extension. With this extension you can generate hash values or HMAC (Hash-based Message Authentication Code). These extensions support the most common hash algorithms used in strong cryptography. If you want to know which algorithms are supported by your PHP environment you can use the function hash_algos() that gives a list of all the algorithms supported. For more information about this extension refer to the PHP manual.

The **mcrypt** extension is an interface to the mcrypt library, which supports a wide variety of block algorithms such as DES, 3DES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA, RC2 and GOST in CBC, OFB, CFB and ECB cipher modes. This extension is the most frequently used method in PHP to encrypt data using symmetric ciphers.

The **OpenSSL** extension uses the functions of the OpenSSL project for generation and verification of signatures and for sealing (encrypting) and opening (decrypting) data. You can use OpenSSL to protect data using public key cryptography with the RSA algorithm.

**Best practices in PHP**

So far we have discussed some general aspects of strong cryptography. We now look at some recommendations for best practice in the field.

– **Use standard algorithms**

Always use a standard algorithm to encrypt your data. Don’t try to implement your homemade cipher, you will spend a lot of time and energy without obtaining any real security. Our primary suggestion is to use the best algorithms available. Example of algorithms which are cryptographically strong are:

– Symmetric-key algorithms: AES, that is a FIST 197 standard since 2001;

– Public-key algorithms: RSA, an industry standard algorithm used in many products;

– Hash functions: SHA-x, where x can be 1,256,384, and 512. SHA is a NIST standard.

– **Key space**

When we talk about the security of a cipher the key space is one of the most important parameters. If no explicit design strength is given by a cipher, the design strength is equal to the key size. For instance, the DES cipher uses 56-bit key, that means the key space is 2^56. This number may seem huge but it is within the grasp of modern computers.

For symmetric ciphers we would say that 128 bit is the minimum size for a strong cryptographic key. With regard to public-key cryptography, experts reccomend a minimum size of 2048 bit or so if we want to protect our data for 20 years.

– **Kerckhof’s principle**

Auguste Kerckhof was a Dutch linguist and cryptographer who was professor of languages at the School of Higher Commercial Studies in Paris in the late 19th century. He wrote, in a famous article of “le Journal des Sciences Militaires”, the following sentence, that is considered seminal in modern cryptography:

A cryptosystem should be secure even if everything about the system, except the key, is public knowledge

Using the Shannon interpretation “The enemy knows the system”. In our opinion, in the software world the only true security is to be achieved by the use of open source algorithms. If the source code has been tested by thousands of people around the world the probability of finding a security bug and consequently a security fix is higher using open source software compared to the usage of closed source.

– **Don’t use rand() or mt_rand()**

You cannot implement a secure random number generator using the rand() function or the mt_rand() function of PHP. The rand() function uses the libc library to generate pseudo-random numbers that would not be secure for cryptographic applications. It generates random numbers using a linear additive feedback method, with a short period, that is predictable. Even the mt_rand() function is not secure from a cryptographic standpoint. It uses the Mersenne Twister algorithm to generate pseudo random numbers. This function is better than the rand() because it faster and it produces pseudo random numbers with a bigger period but is still a deterministic algorithm so is predictable. To generate a cryptographically strong random number in PHP you have to use the function **openssl_random_pseudo_bytes()** from the OpenSSL library. This function is available starting from PHP 5.3 if you are using an oldest version of PHP you can use this implementation:

1 2 3 4 5 6 7 8 9 10 11 12 13 |
function secure_rand($length) { if(function_exists('openssl_random_pseudo_bytes')) { $rnd = openssl_random_pseudo_bytes($length, $strong); if($strong === TRUE) return $rnd; } for ($i=0;$i<$length;$i++) { $sha= sha1(mt_rand()); $char= mt_rand(0,30); $rnd.= chr(hexdec($sha[$char].$sha[$char+1])); } return $rnd; } |

In this implementation we hash the mt_rand() outputs. This method improves the security of the Mersenne Twister but is not the same level of security of the OpenSSL implementation.

– **Use a salt value in hash functions**

If you are using a hash function to protect data, for instance a password, concatenate the data with a random value (salt) befor you generate the hash. A random salt will protect your data from Dictionary attacks.

– **Size and strength of the passwords**

Don’t make it possible for users of your web application to choose small or dummy passwords. You should always use passwords with, at least, 8 characters mixed with numbers and letters. You can use the CrackLib library to test the “strength” of a password.

– **Don’t use plaintext passwords as key for ciphers**

A good practice in cryptography, using symmetric ciphers, is to use a hashed value as the key of a cipher. This method improves the security of the encrypted data by adding more randomness. That means if you want to generate a good key for a cipher you should use the hash of the password and use that as key of your encryption algorithm.

– **Use Base64 to encode encrypted data**

If you need to exchange encrypted data with different systems, for instance, trasmitting data over the internet, it is reccomended to encode the data in Base64. In PHP you can use the functions base64_encode() and base64_decode(). This encoding will guarantee that your data will be stored correctly independently of the encoding system used in your environment.

## 0 Comments