2016-11-29 10 views
0

以下は私のPHPプロジェクトで使用している暗号化クラスです。このクラスは、ここでSOの質問のいずれかに答えとして与えられたように、リンク暗号化を保存する方法MySQLでPHPで双方向暗号化を行った

https://stackoverflow.com/a/5093422/5330647

にある場合は
/** 
* A class to handle secure encryption and decryption of arbitrary data 
* 
* Note that this is not just straight encryption. It also has a few other 
* features in it to make the encrypted data far more secure. Note that any 
* other implementations used to decrypt data will have to do the same exact 
* operations. 
* 
* Security Benefits: 
* 
* - Uses Key stretching 
* - Hides the Initialization Vector 
* - Does HMAC verification of source data 
* 
*/ 
class Encryption { 

    /** 
    * @var string $cipher The mcrypt cipher to use for this instance 
    */ 
    protected $cipher = ''; 

    /** 
    * @var int $mode The mcrypt cipher mode to use 
    */ 
    protected $mode = ''; 

    /** 
    * @var int $rounds The number of rounds to feed into PBKDF2 for key generation 
    */ 
    protected $rounds = 100; 

    /** 
    * Constructor! 
    * 
    * @param string $cipher The MCRYPT_* cypher to use for this instance 
    * @param int $mode The MCRYPT_MODE_* mode to use for this instance 
    * @param int $rounds The number of PBKDF2 rounds to do on the key 
    */ 
    public function __construct($cipher, $mode, $rounds = 100) { 
     $this->cipher = $cipher; 
     $this->mode = $mode; 
     $this->rounds = (int) $rounds; 
    } 

    /** 
    * Decrypt the data with the provided key 
    * 
    * @param string $data The encrypted datat to decrypt 
    * @param string $key The key to use for decryption 
    * 
    * @returns string|false The returned string if decryption is successful 
    *       false if it is not 
    */ 
    public function decrypt($data, $key) { 
     $salt = substr($data, 0, 128); 
     $enc = substr($data, 128, -64); 
     $mac = substr($data, -64); 

     list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key); 

     if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) { 
      return false; 
     } 

     $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv); 

     $data = $this->unpad($dec); 

     return $data; 
    } 

    /** 
    * Encrypt the supplied data using the supplied key 
    * 
    * @param string $data The data to encrypt 
    * @param string $key The key to encrypt with 
    * 
    * @returns string The encrypted data 
    */ 
    public function encrypt($data, $key) { 
     $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM); 
     list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key); 

     $data = $this->pad($data); 

     $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv); 

     $mac = hash_hmac('sha512', $enc, $macKey, true); 
     return $salt . $enc . $mac; 
    } 

    /** 
    * Generates a set of keys given a random salt and a master key 
    * 
    * @param string $salt A random string to change the keys each encryption 
    * @param string $key The supplied key to encrypt with 
    * 
    * @returns array An array of keys (a cipher key, a mac key, and a IV) 
    */ 
    protected function getKeys($salt, $key) { 
     $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode); 
     $keySize = mcrypt_get_key_size($this->cipher, $this->mode); 
     $length = 2 * $keySize + $ivSize; 

     $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length); 

     $cipherKey = substr($key, 0, $keySize); 
     $macKey = substr($key, $keySize, $keySize); 
     $iv = substr($key, 2 * $keySize); 
     return array($cipherKey, $macKey, $iv); 
    } 

    /** 
    * Stretch the key using the PBKDF2 algorithm 
    * 
    * @see http://en.wikipedia.org/wiki/PBKDF2 
    * 
    * @param string $algo The algorithm to use 
    * @param string $key The key to stretch 
    * @param string $salt A random salt 
    * @param int $rounds The number of rounds to derive 
    * @param int $length The length of the output key 
    * 
    * @returns string The derived key. 
    */ 
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) { 
     $size = strlen(hash($algo, '', true)); 
     $len = ceil($length/$size); 
     $result = ''; 
     for ($i = 1; $i <= $len; $i++) { 
      $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true); 
      $res = $tmp; 
      for ($j = 1; $j < $rounds; $j++) { 
       $tmp = hash_hmac($algo, $tmp, $key, true); 
       $res ^= $tmp; 
      } 
      $result .= $res; 
     } 
     return substr($result, 0, $length); 
    } 

    protected function pad($data) { 
     $length = mcrypt_get_block_size($this->cipher, $this->mode); 
     $padAmount = $length - strlen($data) % $length; 
     if ($padAmount == 0) { 
      $padAmount = $length; 
     } 
     return $data . str_repeat(chr($padAmount), $padAmount); 
    } 

    protected function unpad($data) { 
     $length = mcrypt_get_block_size($this->cipher, $this->mode); 
     $last = ord($data[strlen($data) - 1]); 
     if ($last > $length) return false; 
     if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) { 
      return false; 
     } 
     return substr($data, 0, -1 * $last); 
    } 
} 

質問: はどのように私はから返されたMySQLのテーブルに暗号化されたデータを保存しませんこのクラスのencrypt()関数?

ここで、暗号化された文字列は、パスワードが5文字で非常に長く、非ASCII文字が含まれています。

  1. このクラスの出力を保存するために、MySQLテーブルのどの列に使用する必要がありますか?
  2. 適切なサイズのパスワードを暗号化して埋め込むことができる列のサイズはどのくらいですか。

EDIT: この質問が重複としてマークされていたように私はちょうど明確なアイデアを与えるタイトルを編集していました。

双方向の暗号化が既に回答されていたため、私は自分のプロジェクトの答えに与えられたクラスを使用しています。

問題: しかし、このクラスを使用して暗号化された暗号化された値をMySQLデータベーステーブルに保存することはできません。あなたがPHPに組み込まれbcryptの塩を使用することができるとき

+1

なぜ暗号化?その安全なenougthよりも。 – SteffenCH

+0

あなたがリンクした回答がストレージサイズを説明しています。あなたがそれを理解するのに苦労しているなら、その質問にコメントすることは、本質的に重複する新しい質問をするよりも良いかもしれません。 –

+1

[双方向暗号化:取得可能なパスワードを保存する必要があります]の重複している可能性があります(http://stackoverflow.com/questions/5089841/two-way-encryption-i-need-to-store-passwords-that -can-be-retrieved) –

答えて

-1

双方向PHPで暗号化

public function encryptIt($q) { 
$cryptKey = 'qJB0rGtIn5UB1xG03'; 
$qEncoded  = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($cryptKey), $q, MCRYPT_MODE_CBC, md5(md5($cryptKey)))); 
return($qEncoded); 

}

public function decryptIt($q) { 
$cryptKey = 'qJB0rGtIn5UB1xG03'; 
$qDecoded  = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($cryptKey), base64_decode($q), MCRYPT_MODE_CBC, md5(md5($cryptKey))), "\0\4"); 
return($qDecoded); 

}

+0

1. MCRYPT_RIJNDAEL_256を使用しないでください。これは256ビットのブロックサイズを指定しています。これは通常誤って行われます。現在の暗号化規格であるAESである128ビットのブロックサイズを指定する方が良いです。 – zaph

+0

2. mcryptを使用しないことをお勧めします。これはabandonwareです。何年も更新されておらず、標準PKCS#7(néePKCS#5)パディングもサポートされていません。バイナリデータ。 mcryptには、2003年にさかのぼる多くの傑出したバグ(https://sourceforge.net/p/mcrypt/bugs/)があります。PHP 7.2では廃止予定のmcrypt拡張機能は削除されます。代わりに[defuse](https://github.com/defuse/php-encryption)または[RNCryptor](https://github.com/RNCryptor)を使用することを検討してください。これらは完全な解決策を提供し、維持され、正しいものです。 – zaph

+0

3. 'cryptKey'は約42ビットのランダム性しかなく、弱いです。 MD5を使用して鍵を生成することは安全ではありません.PBKDF2、Rfc2898DeriveBytesなどのパスワード導出関数を使用する必要があります(NUST推奨または同等)。 – zaph

関連する問題