Home > Backend Development > PHP Tutorial > PHP Security-Encryption

PHP Security-Encryption

黄舟
Release: 2023-03-05 20:36:01
Original
1103 people have browsed it



Encryption

## As a book about security, encryption is usually a topic that needs to be mentioned. The reason I ignore encryption in the main part of this book is that its use is narrow and developers should think about security in the bigger picture. Overreliance on encryption often obfuscates the source of the problem. Although encryption itself is effective, encrypting it does not magically make an application more secure.

A PHP developer should mainly be familiar with the following encryption methods:

##l Symmetrical Encryption

l Asymmetric encryption (public key)

l Hash function (information summary)

l Message verification code

This appendix mainly focuses on the symmetric encryption algorithm using the mcrypt extension. The information you need to refer to is as follows:

Applied Cryptography, by Bruce Schneier (Wiley)

http://www.php.cn/

##http://www.php.cn/

http://www.php.cn/

http://www.php.cn/

http://www.php.cn/

C.1. Password storage

When you store passwords in a database, never store them in the clear. Instead, store the hash of the password and use the appended string:

<?php
 
  /* $password contains the password. */
 
  $salt = &#39;SHIFLETT&#39;;
  $password_hash = md5($salt . md5($password .
$salt));
 
  /* Store password hash. */
 
  ?>
Copy after login


## When you need to confirm whether a password is correct, calculate it in the same way Get the hash value and compare the similarities and differences:

  <?php
 
  $salt = &#39;SHIFLETT&#39;;
  $password_hash = md5($salt .
md5($_POST[&#39;password&#39;] . $salt));
 
  /* Compare password hashes. */
 
  ?>
Copy after login


## If the hash values ​​are exactly the same, you have reason to think that the passwords are also the same.

If this trick is used, it is impossible to tell the user what their password is. When a user forgets his password, you can only ask him to enter a new password and recalculate the hash value and store it in the database. Of course, you need to be very careful about authenticating users - password reminders are a frequent target of attacks and a frequent source of security breaches.

C.2. Use mcrypt

PHP's standard encryption extension is mcrypt, which supports many different encryption algorithms. You can pass mcrypt_list_algorithms( ) function to view the list of supported algorithms on your platform:

 <?php
 
  echo &#39;<pre class="brush:php;toolbar:false">&#39; .
print_r(mcrypt_list_algorithms(), TRUE) . &#39;
'; ?>
Copy after login


Encryption and decryption are performed by mcrypt_encrypt( ) and mcrypt_decrypt( ) function to implement. Both functions have 5 parameters. 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);
 
  ?>
Copy after login


The encryption key (the second parameter) is very sensitive data, so you want to make sure you store it in a safe place. Encryption keys can be protected using the methods for protecting database permissions in Chapter 8. If financial conditions permit, hardware encryption keys are the best choice, providing super strong security.

The function has multiple modes to choose from, you can use mcrypt_list_modes( ) to list all supported modes:

<?php
 
  echo &#39;<pre class="brush:php;toolbar:false">&#39; . print_r(mcrypt_list_modes(),
TRUE) . &#39;
'; ?>
Copy after login


## The five parameters ($iv) are initialization vectors, which can be created using the mcrypt_create_iv() function.

The following sample class provides 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[&#39;CRYPT_KEY&#39;], $this->cleartext,
$this->mode, $this->iv);
    }
 
    public function decrypt()
    {
      $this->cleartext =
mcrypt_decrypt($this->algorithm,
        $_SERVER[&#39;CRYPT_KEY&#39;], $this->ciphertext,
$this->mode, $this->iv);
    }
  }
 
  ?>
Copy after login

上面的类会在其它示例中使用,下面是它的使用方法示例:

<?php
 
  $crypt = new crypt();
 
  $crypt->cleartext = &#39;This is a string&#39;;
  $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;
 
  ?>
Copy after login


小提示

本扩展要求你在编译PHP时使用-mcrypt标识。安装指南及要求详见http://www.php.cn/。

C.3. 信用卡号的保存

我常常被问到如何安全地保存信用卡号。我的总是会首先询问他们是否确实有必要保存信用卡号。毕竟不管具体是如何操作的,引入不必要的风险是不明智的。同时国家法律还有关于信用卡信息处理方面的规定,我还时刻小心地提醒我并不是一个法律专家。

本书中我并不会专门讨论信用卡处理的方法,而是会说明如何保存加密信息到数据库及在读取时解密。该流程会导致系统性能的下降,但是确实提供了一层保护措施。其主要优点是如果数据库内容泄密暴露出的只是加密信息,但是前提是加密键是安全的。因此,加密键与加密的实现方法本身同样重要。

保存加密数据到数据的过程是,首先加密数据,然后通过初始向量与明文建立密文来保存到数据库。由于密文是二进制字符串,还需要通过base64_encode( )转换成普通文本字符串以保证二进制编码的安全存储。

<?php
 
  $crypt = new crypt();
 
  $crypt->cleartext = &#39;1234567890123456&#39;;
  $crypt->generate_iv();
  $crypt->encrypt();
 
  $ciphertext = $crypt->ciphertext;
  $iv = $crypt->iv;
 
  $string = base64_encode($iv . $ciphertext);
 
  ?>
Copy after login


保存该字串至数据库。在读取时,则是上面流程的逆处理:

  <?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;
 
  ?>
Copy after login


本实现方法假定加密算法与模式不变。如果它们是不定的话,你还要保存它们以用于解密数据。加密键是唯一需要保密的数据。

C.4. 加密会话数据

如果你的数据库存在安全问题,或者部分保存在会话中的数据是敏感的,你可能希望加密会话数据。除非很有必要,一般我不推荐这样做,但是如果你觉得在你的情形下需要这样做的话,本节提供了一个实现方法的示例。

这个方案十分简单。实际上,在第八章中,已经说明了如何通过调用session_set_save_handler( )来执行你自己的会话机制。通过对保存和读取数据的函数的少量调整,你就能加密存入数据库的数据及在读取时解密数据:

 <?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 = &#39;$id&#39;";
 
    if ($result = mysql_query($sql, $_sess_db))
    {
        $record = mysql_fetch_assoc($result);
 
        $data = base64_decode($record[&#39;data&#39;]);
 
        $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 &#39;&#39;;
  }
 
  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  (&#39;$id&#39;, &#39;$access&#39;,
&#39;$data&#39;)";
 
    return mysql_query($sql, $_sess_db);
  }
Copy after login

 以上就是PHP安全-加密的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template