0

ログインしたユーザーがさまざまなアプリケーションのパスワードを MySQL データベースに保存できるようにする Web アプリケーションを作成しようとしています。しかし、MySQL 管理者がこれらのパスワードをデータベースから直接読み取れないようにするために、これらのパスワードをデータベースに送信する前に読み取れないようにしたいと考えています。次に、ユーザーが保存されたパスワードを確認したい場合、Web アプリケーションは保存されたパスワードを解読し、画面に表示します。

これらのパスワードを暗号化してデータベースに保存し、データベースから読み取ったときに復号化する方法を考えています。

たとえば、次のようになります。 - ユーザーは新しいパスワードを保存したいと考えています: Abc123! - 次に、Web アプリケーションは、指定されたパスワードを「意味のない」ものに変換します: 234fohj234]j8924] (または同様のもの) をデータベースに保存します。- ユーザーが Web アプリケーションを開いて保存されているパスワードを確認すると、正しいパスワードが表示されます: Abc123! - しかし、MySQL 管理者が PHPMyAdmin のようなプログラムを使用してデータベースを表示/維持すると、実際のパスワードではなく、「意味不明な」パスワードしか表示されません。

PHP (または MySQL) は、このような機能を内蔵していますか? または、これを達成するための関数を作成するためのヒントはありますか?

4

1 に答える 1

0

PHP は、双方向暗号化を使用するための MCrypt ライブラリを提供します。最大の問題は鍵をどこに保管するかですが、これは別問題です。提供できる最善の保護は、(暗号化に使用される) キーをまったく保存せず、ユーザーがサービスを使用するたびにキーを入力できるようにすることです。欠点は、この方法ではパスワードを忘れた場合の機能が利用できないことです。

暗号化に ECB モードを使用しないように注意してください。同じパスワードは常に同じ暗号文になります。代わりに、ランダムな IV ベクトルを使用する別のモードを使用してください。PHP マニュアルには ECB モードを使用する例があるため、IV ベクトルを使用して結果に格納する小さな例を追加しました。

/**
 * Encrypts data with the TWOFISH algorithm. The IV vector will be
 * included in the resulting binary string.
 * @param string $data Data to encrypt. Trailing \0 characters will get lost.
 * @param string $key This key will be used to encrypt the data. The key
 *   will be hashed to a binary representation before it is used.
 * @return string Returns the encrypted data in form of a binary string.
 */
function encryptTwofish($data, $key)
{
  if (!defined('MCRYPT_DEV_URANDOM')) throw new Exception('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).');
  if (!defined('MCRYPT_TWOFISH')) throw new Exception('The MCRYPT_TWOFISH algorithm is required (PHP 5.3).');

  // The cbc mode is preferable over the ecb mode
  $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, '');

  // Twofish accepts a key of 32 bytes. Because usually longer strings
  // with only readable characters are passed, we build a binary string.
  $binaryKey = hash('sha256', $key, true);

  // Create initialization vector of 16 bytes
  $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM);

  mcrypt_generic_init($td, $binaryKey, $iv);
  $encryptedData = mcrypt_generic($td, $data);
  mcrypt_generic_deinit($td);
  mcrypt_module_close($td);

  // Combine iv and encrypted text
  return $iv . $encryptedData;
}

/**
 * Decrypts data, formerly encrypted with @see encryptTwofish.
 * @param string $encryptedData Binary string with encrypted data.
 * @param string $key This key will be used to decrypt the data.
 * @return string Returns the original decrypted data.
 */
function decryptTwofish($encryptedData, $key)
{
  if (!defined('MCRYPT_TWOFISH')) throw new Exception('The MCRYPT_TWOFISH algorithm is required (PHP 5.3).');

  $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, '');

  // Extract initialization vector from encrypted data
  $ivSize = mcrypt_enc_get_iv_size($td);
  $iv = substr($encryptedData, 0, $ivSize);
  $encryptedData = substr($encryptedData, $ivSize);

  $binaryKey = hash('sha256', $key, true);

  mcrypt_generic_init($td, $binaryKey, $iv);
  $decryptedData = mdecrypt_generic($td, $encryptedData);
  mcrypt_generic_deinit($td);
  mcrypt_module_close($td);

  // Original data was padded with 0-characters to block-size
  return rtrim($decryptedData, "\0");
}
于 2013-09-30T15:19:11.470 に答える