简体   繁体   中英

store / read passwords into / from database

I'm trying to write a web application that allows logged in users to store passwords for different applications into a MySQL db. But to prevent MySQL admins from reading those passwords directly from the db, I'd like to make those passwords unreadable before they're send to the db. Then when the user wishes to look at his stored passwords the web application decrypts the stored passwords and shows them on screen.

I'm trying to work out a method of encrypting those passwords for storage in the db and then decrypt them when read from the db.

So, for example: - The user wishes to store a new password: Abc123! - The web application then transforms the given password into 'gibberish': 234fohj234]j8924] (or something similar) and stores it into the db. - When the user opens the web application to look at his stored passwords, he sees the correct password: Abc123! - But when an MySQL admin uses a program like PHPMyAdmin to view / maintain the database, he will only see the 'gibberish' password, not the real one.

Does PHP (or MySQL) offer a build-in function for something like this? Or does anyone have any tips on creating a function to accomplish this?

PHP offers the MCrypt library to use two-way encryption. The biggest problem is where to store the key, but this is another question. The best protection you can give, is when you do not store the key (used for encryption) at all, and let the user enter a key every time he uses your service. The downside is, that a forgotten-password function is not possible this way.

Be careful not to use the ECB mode for encryption, the same password will always result in the same cyphertext, instead use another mode with a random IV-vector. Since there are examples in the PHP manual, which use the ECB mode, i added a small example, that uses an IV-vector and stores it in the result.

/**
 * 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");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM