A PHP developer should be primarily familiar with the following encryption methods:
L Symmetric encryption
L Asymmetric encryption (public key)
L hash function (Information Digest)
L Information Verification Code
This appendix focuses on symmetric encryption algorithms that use MCrypt extensions. You need to refer to the following information:
Practical encryption Technology (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. Storage of passwords
When you store passwords in a database, you should never store them in plaintext, but you should save the hash value of the password and use additional strings at the same time:
<?php/ * $password contains the password. */ $salt = ' Shiflett '; $password _hash = MD5 ($salt. MD5 ($password. $salt)); /* Store password hash. */ ?>
when you need to verify that a password is correct, calculate the hash value in the same way and compare the similarities and differences:
<?php $salt = ' Shiflett '; $password _hash = MD5 ($salt. MD5 ($_post[' password ']. $salt)); /* Compare password hashes. */ ?>
If the hash value is exactly the same, you have reason to think that the password is the same.
If you use this technique, it is impossible to tell the user what their password is. When the user forgets the password, you can only let him enter a new password and recalculate the hash value into the database. Of course, you need to be very careful about authenticating your users-the password-alerting mechanism is the target of frequent attacks and the source of frequent security breaches.
C.2. Using MCrypt
PHP's standard encryption extension is mcrypt, which supports a number of different cryptographic algorithms. You can use the Mcrypt_list_algorithms () function to see a list of the algorithms supported on your platform:
<?php Echo ' <pre> '. Print_r (Mcrypt_list_algorithms (), TRUE). ' </pre> '; ? >
encryption and decryption are implemented by the Mcrypt_encrypt () and the Mcrypt_decrypt () function respectively. Both functions have 5 parameters, and the first parameter is used to specify the algorithm used:
<?php Mcrypt_encrypt ($algorithm, $key, $cleartext, $mode, $iv); Mcrypt_decrypt ($algorithm, $key, $ciphertext, $mode, $iv); ? >
the Encryption key (the second parameter) is very sensitive data, so make sure you keep it in a safe place. You can protect the encryption key by using the method of protecting database permissions in chapter eighth. If the economic conditions allow, the hardware encryption key is the best choice, it provides super-powerful security.
The functions are available in a variety of modes, and you can use Mcrypt_list_modes () to list all supported modes:
<?php Echo ' <pre> '. Print_r (Mcrypt_list_modes (), TRUE). ' </pre> '; ? >
The fifth parameter ($IV) is an initialization vector, which can be established using the Mcrypt_create_iv () function.
The following example class provides a basic method for encrypting and decrypting:
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; The 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[' Cryp T_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 is used in other examples, here is an example of how it is used:
<?php $crypt = new Crypt (); $crypt->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;? >
Little Tips
This extension requires that you use the-mcrypt identity when compiling PHP. Installation instructions and requirements are described in Http://php.net/mcrypt.
C.3. Retention of credit card numbers
I was often asked how to safely save credit card numbers. I always ask first whether they really need to save the credit card number. After all, no matter how it is done, it is unwise to introduce unnecessary risks. There are also national laws on credit card information processing, and I am always careful to remind me that I am not a legal expert.
In this book I do not specifically discuss the method of credit card processing, but will explain how to save the encrypted information to the database and read the decryption. This process can lead to degraded system performance, but it does provide a layer of protection. The main advantage is that if the database content leaks out only encrypted information, but only if the encryption key is secure. Therefore, encryption keys are as important as the encryption implementation itself.
The process of saving the encrypted data to the data is to encrypt the data first and then save the redaction to the database through the initial vector and the plaintext. Since ciphertext is a binary string, it also needs to be converted to a normal text string by Base64_encode () to secure the binary encoded storage.
<?php $crypt = new Crypt (); $crypt->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 process of the above process:
<?php $string = Base64_decode ($string); $iv _size = mcrypt_get_iv_size ($algorithm, $mode); $ciphertext = substr ($string, $iv _size); $iv = substr ($string, 0, $iv _size); $crypt = new Crypt (); $crypt->iv = $iv; $crypt->ciphertext = $ciphertext; $crypt->decrypt (); $cleartext = $crypt->cleartext; ? >
The implementation method assumes that the encryption algorithm and mode are not changed. If they are not, you also need to save them for decrypting the data. Encryption keys are the only data that needs to be kept secret.
C.4. Encrypting session Data
You may want to encrypt session data if your database has security issues, or if some of the data stored in the session is sensitive. Unless it is necessary, generally I do not recommend this, but if you feel that you need to do so in your case, this section provides an example of the implementation method.
This scheme is very simple. In fact, in the eighth chapter, it has been explained how to execute your own session mechanism by calling Session_set_save_handler (). By using a small amount of adjustments to the functions of saving and reading data, you can encrypt the data stored in the database and decrypt the data as it is read:
<?php function _read ($id) {global $_sess_db; $algorithm = Mcrypt_blowfish; $mode = MCRYPT_MODE_CBC; $id = mysql_real_escape_string ($id); $sql = "Select data from sessions WHERE ID = ' $id '"; if ($result = mysql_query ($sql, $_sess_db)) {$record = Mysql_fetch_assoc ($result); $data = Base64_decode ($record [' data ']); $iv _size = mcrypt_get_iv_size ($algorithm, $mode); $ciphertext = substr ($data, $iv _size); $iv = substr ($data, 0, $iv _size); $crypt = new Crypt (); $crypt->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); }?>