What I mean is:
Original String + Salt or Key --> Encrypted String
Encrypted String + Salt or Key --> Decrypted (Original String)
Maybe something like:
"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"
- In PHP, how can you do this?
Attempted to use Crypt_Blowfish
, but it didn't work for me.
If you don't want to use library (which you should) then use something like this (PHP 7):
I'm late to the party, but searching for the correct way to do it I came across this page it was one of the top Google search returns, so I will like to share my view on the problem, which I consider it to be up to date at the time of writing this post (beginning of 2017). From PHP 7.1.0 the
mcrypt_decrypt
andmcrypt_encrypt
is going to be deprecated, so building future proof code should use openssl_encrypt and openssl_decryptYou can do something like:
You can use any other chipper methods as well, depending on your security need. To find out the available chipper methods please see the openssl_get_cipher_methods function.
For Laravel framework
If you are using Laravel framework then it's more easy to encrypt and decrypt with internal functions.
What not to do
I got it on myself. Actually i found some answer on google and just modified something. The result is completely insecure however.
Before you do anything further, seek to understand the difference between encryption and authentication, and why you probably want authenticated encryption rather than just encryption.
To implement authenticated encryption, you want to Encrypt then MAC. The order of encryption and authentication is very important! One of the existing answers to this question made this mistake; as do many cryptography libraries written in PHP.
You should avoid implementing your own cryptography, and instead use a secure library written by and reviewed by cryptography experts.
Use libsodium if you have PECL access (or sodium_compat if you want libsodium without PECL); otherwise...
Use defuse/php-encryption; don't roll your own cryptography!
Both of the libraries linked above above make it easy and painless to implement authenticated encryption into your own libraries.
If you still want to write and deploy your own cryptography library, against the conventional wisdom of every cryptography expert on the Internet, these are the steps you would have to take.
Encryption:
Decryption:
hash_equals()
. If it fails, abort.Other Design Considerations:
mb_strlen()
andmb_substr()
, using the'8bit'
character set mode to preventmbstring.func_overload
issues.mcrypt_create_iv()
, DO NOT USEMCRYPT_RAND
!bin2hex()
,base64_encode()
, etc. may leak information about your encryption keys via cache timing. Avoid them if possible.Even if you follow the advice given here, a lot can go wrong with cryptography. Always have a cryptography expert review your implementation. If you are not fortunate enough to be personal friends with a cryptography student at your local university, you can always try the Cryptography Stack Exchange forum for advice.
If you need a professional analysis of your implementation, you can always hire a reputable team of security consultants to review your PHP cryptography code (disclosure: my employer).
Important: When to Not Use Encryption
Don't encrypt passwords. You want to hash them instead, using one of these password-hashing algorithms:
Never use a general-purpose hash function (MD5, SHA256) for password storage.
Don't encrypt URL Parameters. It's the wrong tool for the job.
PHP String Encryption Example with Libsodium
If you are on PHP < 7.2 or otherwise do not have libsodium installed, you can use sodium_compat to accomplish the same result (albeit slower).
Then to test it out:
Halite - Libsodium Made Easier
One of the projects I've been working on is an encryption library called Halite, which aims to make libsodium easier and more intuitive.
All of the underlying cryptography is handled by libsodium.
Example with defuse/php-encryption
Note:
Crypto::encrypt()
returns hex-encoded output.Encryption Key Management
If you're tempted to use a "password", stop right now. You need a random 128-bit encryption key, not a human memorable password.
You can store an encryption key for long-term use like so:
And, on demand, you can retrieve it like so:
I strongly recommend just storing a randomly generated key for long-term use instead of any sort of password as the key (or to derive the key).
If you're using Defuse's library:
$string = $keyObject->saveToAsciiSafeString()
$loaded = Key::loadFromAsciiSafeString($string);
"But I really want to use a password."
That's a bad idea, but okay, here's how to do it safely.
First, generate a random key and store it in a constant.
Note that you're adding extra work and could just use this constant as the key and save yourself a lot of heartache!
Then use PBKDF2 (like so) to derive a suitable encryption key from your password rather than encrypting with your password directly.
Don't just use a 16-character password. Your encryption key will be comically broken.
I have left this answer for historical purposes - but some of the methods are now deprecated, DES encryption method is not a recommended practice, etc.
I have not updated this code for two reasons: 1) I no longer work with encryption methods by hand in PHP, and 2) this code still serves the purpose it was intended for: to demonstrate the minimum, simplistic concept of how encryption can work in PHP.
If you find a similarly simplistic, "PHP encryption for dummies" kind of source that can get people started in 10-20 lines of code or less, let me know in comments.
Beyond that, please enjoy this Classic Episode of early-era PHP4 minimalistic encryption answer.
Ideally you have - or can get - access to the mcrypt PHP library, as its certainly popular and very useful a variety of tasks. Here's a run down of the different kinds of encryption and some example code: Encryption Techniques in PHP
A few warnings:
1) Never use reversible, or "symmetric" encryption when a one-way hash will do.
2) If the data is truly sensitive, like credit card or social security numbers, stop; you need more than any simple chunk of code will provide, but rather you need a crypto library designed for this purpose and a significant amount of time to research the methods necessary. Further, the software crypto is probably <10% of security of sensitive data. It's like rewiring a nuclear power station - accept that the task is dangerous and difficult and beyond your knowledge if that's the case. The financial penalties can be immense, so better to use a service and ship responsibility to them.
3) Any sort of easily implementable encryption, as listed here, can reasonably protect mildly important information that you want to keep from prying eyes or limit exposure in the case of accidental/intentional leak. But seeing as how the key is stored in plain text on the web server, if they can get the data they can get the decryption key.
Be that as it may, have fun :)