首頁 後端開發 php教程 php安全加密技術

php安全加密技術

Nov 21, 2016 pm 04:11 PM
php

 一個PHP開發者應主要熟悉以下的加密方式:

 

l        對稱加密金鑰

l             資訊驗證碼

 

  本附錄主要關注使用mcrypt擴展的對稱加密演算法。需要參考的資料如下:

 

  實用加密技術(Applied Cryptography), by Bruce Schneier (Wiley)

http://www.schneier.com/blog/

http://wiki

http://www.schneier.com/blog/

http://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. 密碼的儲存

  當你在資料庫內儲存的密碼時,永遠不要以明碼方式存入,而是應該儲存密碼的hash值並同時使用附加字串:

 

<?php
 
  /* $password contains the password. */
 
  $salt = &#39;SHIFLETT&#39;;
  $password_hash = md5($salt . md5($password . $salt));
 
  /* Store password hash. */
 
  ?>
登入後複製

 

當你需要確認一個密碼是否正確時,以同樣的方式計算出hash值並比較異同:

<?php
 
  $salt = &#39;SHIFLETT&#39;;
  $password_hash = md5($salt . md5($_POST[&#39;password&#39;] . $salt));
 
  /* Compare password hashes. */
 
  ?>
登入後複製

 

  如果hash值完全相同,你就有理由認為密碼也是相同的。

  如果使用了這個技巧,是不可能告訴使用者他們的密碼是什麼的。當使用者忘記密碼時,你只能讓他輸入一個新密碼並重新計算hash值存入資料庫。當然,你需要非常小心地對使用者進行身分確認──密碼提醒機制是容易受到頻繁攻擊的目標,​​同時也是經常出現安全漏洞的來源。

 

C.2. 使用mcrypt

  PHP的標準加密擴充是mcrypt,它支援許多不同的加密演算法。你可以透過mcrypt_list_algorithms( )函數來查看你的平台上支援的演算法列表:

 

<?php
 
  echo &#39;<pre class="brush:php;toolbar:false">&#39; . print_r(mcrypt_list_algorithms(), TRUE) . &#39;
'; ?>
登入後複製

 

  加密和解密分別由mcrypt_encrypt( ) 和 mcrypt_decrypt( )函數來實現。這兩個函數都有5個參數,第一個參數是用來指定使用的演算法:

 <?php
 
  mcrypt_encrypt($algorithm,
                 $key,
                 $cleartext,
                 $mode,
                 $iv);
 
  mcrypt_decrypt($algorithm,
                 $key,
                 $ciphertext,
                 $mode,
                 $iv);
 
  ?>
登入後複製

 

 其中的加密鍵(第二個參數)是非常敏感的數據,因此你要確保把它存放在安全的地方。可以用第八章保護資料庫權限的方法來保護加密鍵。如果經濟條件允許的話,硬體加密鍵是最好的選擇,它提供了超級強大的安全性。

  函數有多種模式可供選擇,你可以使用mcrypt_list_modes( )來列出所有支援的模式:

<?php
 
  echo &#39;<pre class="brush:php;toolbar:false">&#39; . print_r(mcrypt_list_modes(), TRUE) . &#39;
'; ?>
登入後複製

 

第五個參數($iv)為初始化向量,可以使用mcrypt_create_iv( )函數建立。

  下列的範例類別提供了基本的加密解密方法:

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);
    }
  }
 
  ?>
登入後複製

 

  上面的類別會在其它範例中使用,以下是它的使用方法範例:

<?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;
?>
登入後複製
擴充提示你在編譯PHP時使用-mcrypt標識。安裝指南及要求詳見http://php.net/mcrypt。

 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);
 
  ?>
登入後複製

 

將該字串保存到資料庫中。在讀取時,則是上面流程的逆處理:

 <?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;
 
  ?>
登入後複製

 

 本實作方法假定加密演算法與模式不變。如果它們是不定的話,你還要保存它們以用於解密資料。加密鍵是唯一需要保密的資料。

 

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);
  }
  ?>
登入後複製


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

討論 CakePHP 討論 CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP 是 PHP 的開源框架。它旨在使應用程式的開發、部署和維護變得更加容易。 CakePHP 基於類似 MVC 的架構,功能強大且易於掌握。模型、視圖和控制器 gu

CakePHP 檔案上傳 CakePHP 檔案上傳 Sep 10, 2024 pm 05:27 PM

為了進行文件上傳,我們將使用表單助理。這是文件上傳的範例。

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

CakePHP 快速指南 CakePHP 快速指南 Sep 10, 2024 pm 05:27 PM

CakePHP 是一個開源MVC 框架。它使應用程式的開發、部署和維護變得更加容易。 CakePHP 有許多函式庫可以減少大多數常見任務的過載。

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

See all articles