phpセキュリティ暗号化技術

伊谢尔伦
伊谢尔伦オリジナル
2016-11-21 16:11:571049ブラウズ

PHP 開発者は主に次の暗号化方式に精通している必要があります:

l 対称暗号化

l . アウト アウト オフ アウトの ''s '' のホルダーの ‐ ‐‐ ‐‐‐ ‐

この付録では、mcrypt 拡張機能を使用した対称暗号化アルゴリズムに焦点を当てています。参照する必要がある情報は次のとおりです。

Applied Cryptography、Bruce Schneier (Wiley) 著

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

http://wikipedia.org/wiki /暗号化

http://phpsec.org/articles/2005/password-hashing.html

http://pear.php.net/package/Crypt_HMAC

http://pear.php.net/package/Crypt_RSA

C.1. パスワードの保存

パスワードをデータベースに保存する場合は、パスワードのハッシュ値を保存し、同時に追加の文字列を使用してください。 パスワードが正しいかどうかを確認する必要がある場合は、同じ方法でハッシュ値を計算し、類似点と相違点を比較してください:

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

ハッシュ値がまったく同じであれば、次のように考える理由があります。パスワードも同じです。

このトリックが使用されると、ユーザーにパスワードを伝えることは不可能になります。ユーザーがパスワードを忘れた場合、新しいパスワードを入力し、ハッシュ値を再計算してデータベースに保存するよう求めることしかできません。もちろん、ユーザーの認証には細心の注意を払う必要があります。パスワード リマインダーは頻繁に攻撃の対象となり、セキュリティ侵害の原因にもなります。

C.2. mcrypt の使用

PHP の標準暗号化拡張機能は mcrypt であり、さまざまな暗号化アルゴリズムをサポートしています。 mcrypt_list_algorithms() 関数を通じて、プラットフォームでサポートされているアルゴリズムのリストを表示できます。

<?php
 
  $salt = &#39;SHIFLETT&#39;;
  $password_hash = md5($salt . md5($_POST[&#39;password&#39;] . $salt));
 
  /* Compare password hashes. */
 
  ?>
暗号化と復号化は、それぞれ mcrypt_encrypt() 関数と mcrypt_decrypt() 関数によって実装されます。どちらの関数にも 5 つのパラメーターがあり、最初のパラメーターは使用するアルゴリズムを指定するために使用されます:

<?php
 
  echo &#39;<pre class="brush:php;toolbar:false">&#39; . print_r(mcrypt_list_algorithms(), TRUE) . &#39;
'; ?> 暗号化キー (2 番目のパラメーター) は非常に機密データであるため、必ず安全な場所に保管する必要があります。暗号化キーは、第 8 章のデータベース権限を保護する方法を使用して保護できます。経済状況が許せば、非常に強力なセキュリティを提供するハードウェア暗号化キーが最良の選択です。

この関数には複数のモードから選択できます。 mcrypt_list_modes() を使用して、サポートされているすべてのモードをリストできます:

 <?php
 
  mcrypt_encrypt($algorithm,
                 $key,
                 $cleartext,
                 $mode,
                 $iv);
 
  mcrypt_decrypt($algorithm,
                 $key,
                 $ciphertext,
                 $mode,
                 $iv);
 
  ?>

5 番目のパラメーター ($iv) は、mcrypt_create_iv() 関数を使用して作成できる初期化ベクトルです。 。

次のクラス例は、基本的な暗号化および復号化メソッドを提供します:

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

上記のクラスは他の例で使用されます。以下はその使用例です:

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 をコンパイルするときに -mcrypt フラグを使用します。インストール手順と要件については、http://php.net/mcrypt を参照してください。

C.3. クレジット カード番号の保存

クレジット カード番号を安全に保存する方法についてよく質問されます。私の場合はいつも、クレジット カード番号を本当に保存する必要があるかどうかを尋ねることから始まります。結局のところ、どのように行うとしても、不必要なリスクを持ち込むのは賢明ではありません。同時に、国内法にもクレジットカード情報の処理に関する規制があり、私は法律の専門家ではないことを常に自分に言い聞かせています。

この本では、クレジットカードの処理方法については特に説明しませんが、暗号化された情報をデータベースに保存し、読み取り時に復号化する方法について説明します。このプロセスによりシステムのパフォーマンスが低下しますが、保護層は提供されます。その主な利点は、データベースのコンテンツが侵害された場合に、暗号化された情報のみが公開されることですが、その前提として暗号化キーが安全であることが挙げられます。したがって、暗号化キーは暗号化自体の実装と同じくらい重要です。

暗号化されたデータをデータに保存するプロセスは、まずデータを暗号化し、次に初期ベクトルと平文を通じて暗号文を作成し、データベースに保存します。暗号文はバイナリ文字列であるため、バイナリ エンコードを安全に保存するには、base64_encode() を通じて通常のテキスト文字列に変換する必要があります。

<?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
 
  $crypt = new crypt();
 
  $crypt->cleartext = &#39;1234567890123456&#39;;
  $crypt->generate_iv();
  $crypt->encrypt();
 
  $ciphertext = $crypt->ciphertext;
  $iv = $crypt->iv;
 
  $string = base64_encode($iv . $ciphertext);
 
  ?>
この実装方法は、暗号化アルゴリズムとモードが変更されていないことを前提としています。定義されていない場合は、データの復号化に使用するために保存する必要もあります。暗号化キーは、秘密にしておく必要がある唯一のデータです。

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 までご連絡ください。