Although encryption is effective, encryption does not magically improve the security of an application. a PHP developer should be familiar with the following encryption methods:
L symmetric encryption
L asymmetric encryption (public key)
L Hash function (Information Summary)
L information verification code
This appendix focuses on symmetric encryption algorithms extended by mcrypt. You need to refer to the following materials:
Applied Cryptography, by Bruce Schneier (Wiley)
Http://www.schneier.com/blog/
Http://wikipedia.org/wiki/Cryptography
Http://phpsec.org/articles/2005/password-hashing.html
Http://pear.php.net/package/Crypt_HMAC
Http://pear.php.net/package/Crypt_RSA
C.1. password storage
When you store a password in a database, you should never store it in plaintext mode. Instead, you should store the hash value of the password and use additional strings at the same time:
When you need to confirm whether a password is correct, calculate the hash value in the same way and compare the similarities and differences:
If the hash value is the same, you have reason to think that the password is the same.
If this technique is used, it is impossible to tell the user what their password is. When a user forgets the password, you can only ask him to enter a new password and re-calculate the hash value and save it to the database. Of course, you need to be very careful with the user's identity confirmation-the password reminder mechanism is vulnerable to frequent attacks and is also the source of frequent security vulnerabilities.
C.2. use mcrypt
The standard encryption extension of PHP is mcrypt, which supports many different encryption algorithms. You can use the mcrypt_list_algorithms () function to view the list of algorithms supported on your platform:
' . print_r(mcrypt_list_algorithms(), TRUE) . '
';?>
Encryption and decryption are implemented by the mcrypt_encrypt () and mcrypt_decrypt () functions. Both functions have five parameters. The first parameter is used to specify the algorithm used:
The encryption key (the second parameter) is very sensitive data, so make sure that it is stored in a safe place. You can use the method of protecting Database permissions in chapter 8 to protect the encryption key. If economic conditions permit, the hardware encryption key is the best choice, providing super powerful security.
The function has multiple modes to choose from. you can use mcrypt_list_modes () to list all supported modes:
' . print_r(mcrypt_list_modes(), TRUE) . '
';?>
The fifth parameter ($ iv) is the initialization vector, which can be created using the mcrypt_create_iv () function.
The following example provides the basic encryption and decryption methods:
class crypt { private $algorithm; private $mode; private $random_source; public $cleartext; public $ciphertext; public $iv; public function __construct($algorithm = MCRYPT_BLOWFISH, $mode = MCRYPT_MODE_CBC, $random_source = MCRYPT_DEV_URANDOM) { $this->algorithm = $algorithm; $this->mode = $mode; $this->random_source = $random_source; } public function generate_iv() { $this->iv = mcrypt_create_iv(mcrypt_get_iv_size($this->algorithm, $this->mode), $this->random_source); } public function encrypt() { $this->ciphertext = mcrypt_encrypt($this->algorithm, $_SERVER['CRYPT_KEY'], $this->cleartext, $this->mode, $this->iv); } public function decrypt() { $this->cleartext = mcrypt_decrypt($this->algorithm, $_SERVER['CRYPT_KEY'], $this->ciphertext, $this->mode, $this->iv); } } ?>
The above class will be used in other examples. Below is an example of its usage:
cleartext = 'This is a string'; $crypt->generate_iv(); $crypt->encrypt(); $ciphertext = base64_encode($crypt->ciphertext); $iv = base64_encode($crypt->iv); unset($crypt); /* Store $ciphertext and $iv (initialization vector). */ $ciphertext = base64_decode($ciphertext); $iv = base64_decode($iv); $crypt = new crypt(); $crypt->iv = $iv; $crypt->ciphertext = $ciphertext; $crypt->decrypt(); $cleartext = $crypt->cleartext;?>
Tips
This extension requires you to use the-mcrypt identifier when compiling PHP. For the installation guide and requirements, see http://php.net/mcrypt.
C.3. saving credit card numbers
I am often asked how to save my credit card number safely. I always first ask them if they really need to save the credit card number. After all, it is unwise to introduce unnecessary risks no matter how they are operated. At the same time, there are also national laws and regulations on credit card information processing, and I am always reminded with caution that I am not a legal expert.
In this book, I will not specifically discuss how to deal with credit card processing, but will explain how to save encrypted information to the database and decrypt it during reading. This process may lead to a reduction in system performance, but does provide a protection measure. The main advantage is that if the database content leaks, only encrypted information is exposed, but the premise is that the encryption key is secure. Therefore, encryption keys and encryption implementation methods are equally important.
The process of saving encrypted data to the data is to encrypt the data first, and then establish a secret with the plaintext through the initial vector to save it to the database. Because ciphertext is a binary string, base64_encode () must be used to convert it into a common text string to ensure safe storage of binary encoding.
cleartext = '1234567890123456'; $crypt->generate_iv(); $crypt->encrypt(); $ciphertext = $crypt->ciphertext; $iv = $crypt->iv; $string = base64_encode($iv . $ciphertext); ?>
Save the string to the database. When reading, it is the inverse processing of the above process:
iv = $iv; $crypt->ciphertext = $ciphertext; $crypt->decrypt(); $cleartext = $crypt->cleartext; ?>
This implementation method assumes that the encryption algorithm and mode remain unchanged. If they are not, you need to save them for data decryption. The encryption key is the only data that requires confidentiality.
C.4. encrypt session data
If your database has security issues or some data stored in the session is sensitive, you may want to encrypt the session data. Unless necessary, I do not recommend this method. However, if you think this is required in your case, this section provides an example of the implementation method.
This solution is very simple. In fact, chapter 8 describes how to execute your own session mechanism by calling session_set_save_handler. With a few adjustments to the function for saving and reading data, you can encrypt the data stored in the database and decrypt the data when reading:
iv = $iv; $crypt->ciphertext = $ciphertext; $crypt->decrypt(); return $crypt->cleartext; } return ''; } function _write($id, $data) { global $_sess_db; $access = time(); $crypt = new crypt(); $crypt->cleartext = $data; $crypt->generate_iv(); $crypt->encrypt(); $ciphertext = $crypt->ciphertext; $iv = $crypt->iv; $data = base64_encode($iv . $ciphertext); $id = mysql_real_escape_string($id); $access = mysql_real_escape_string($access); $data = mysql_real_escape_string($data); $sql = "REPLACE INTO sessions VALUES ('$id', '$access', '$data')"; return mysql_query($sql, $_sess_db); } ?>