What is the simplest way of doing two way encryption in common PHP installs?
I need to be able to encrypt data with a string key, and use the same key to decrypt on the other end.
The security isn't as big of a concern as the portability of the code, so I'd like to be able to keep things as simple as possible. Currently, I am using an RC4 implementation, but if I can find something natively supported I figure I can save a lot of unnecessary code.
Important: Unless you have a very particular use-case, do not encrypt passwords, use a password hashing algorithm instead. When someone says they encrypt their passwords in a server-side application, they're either uninformed or they're describing a dangerous system design. Safely storing passwords is a totally separate problem from encryption.
Be informed. Design safe systems.
Portable Data Encryption in PHP
If you're using PHP 5.4 or newer and don't want to write a cryptography module yourself, I recommend using an existing library that provides authenticated encryption. The library I linked relies only on what PHP provides and is under periodic review by a handful of security researchers. (Myself included.)
If your portability goals do not prevent requiring PECL extensions, libsodium is highly recommended over anything you or I can write in PHP.
Update (2016-06-12): You can now use sodium_compat and use the same crypto libsodium offers without installing PECL extensions.
If you want to try your hand at cryptography engineering, read on.
First, you should take the time to learn the dangers of unauthenticated encryption and the Cryptographic Doom Principle.
Encryption and Decryption
Encryption in PHP is actually simple (we're going to use
openssl_encrypt()
andopenssl_decrypt()
once you have made some decisions about how to encrypt your information. Consultopenssl_get_cipher_methods()
for a list of the methods supported on your system. The best choice is AES in CTR mode:aes-128-ctr
aes-192-ctr
aes-256-ctr
There is currently no reason to believe that the AES key size is a significant issue to worry about (bigger is probably not better, due to bad key-scheduling in the 256-bit mode).
Note: We are not using
mcrypt
because it is abandonware and has unpatched bugs that might be security-affecting. Because of these reasons, I encourage other PHP developers to avoid it as well.Simple Encryption/Decryption Wrapper using OpenSSL
Usage Example
Demo: https://3v4l.org/jl7qR
The above simple crypto library still is not safe to use. We need to authenticate ciphertexts and verify them before we decrypt.
Note: By default,
UnsafeCrypto::encrypt()
will return a raw binary string. Call it like this if you need to store it in a binary-safe format (base64-encoded):Demo: http://3v4l.org/f5K93
Simple Authentication Wrapper
Usage Example
Demos: raw binary, base64-encoded
If anyone wishes to use this
SaferCrypto
library in a production environment, or your own implementation of the same concepts, I strongly recommend reaching out to your resident cryptographers for a second opinion before you do. They'll be able tell you about mistakes that I might not even be aware of.You will be much better off using a reputable cryptography library.
PHP 7.2 moved completely away from
Mcrypt
and the encryption now is based on the maintainableLibsodium
library.All your encryption needs can be basically resolved through
Libsodium
library.Libsodium documentation: https://github.com/paragonie/pecl-libsodium-doc
Edited:
You should really be using openssl_encrypt() & openssl_decrypt()
As Scott says, Mcrypt is not a good idea as it has not been updated since 2007.
There is even an RFC to remove Mcrypt from PHP - https://wiki.php.net/rfc/mcrypt-viking-funeral
Super simple one-lined native ways to OBFUSCATE (pseudo encrypt/decrypt), without any keys or external libraries:
These are the simplest ways of doing two way obfuscation in common PHP installs.
Use
mcrypt_encrypt()
andmcrypt_decrypt()
with corresponding parameters. Really easy and straight forward, and you use a battle-tested encryption package.EDIT
5 years and 4 months after this answer, the
mcrypt
extension is now in the process of deprecation and eventual removal from PHP.Here is simple but secure enough implementation:
Code and examples are here: https://stackoverflow.com/a/19445173/1387163