简体   繁体   English

存储密码/从数据库读取密码

[英]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. 我正在尝试编写一个Web应用程序,该应用程序允许登录的用户将不同应用程序的密码存储到MySQL数据库中。 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. 但是,为了防止MySQL管理员直接从数据库读取这些密码,我希望在将这些密码发送到数据库之前使其不可读。 Then when the user wishes to look at his stored passwords the web application decrypts the stored passwords and shows them on screen. 然后,当用户希望查看其存储的密码时,Web应用程序将对存储的密码进行解密并将其显示在屏幕上。

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! 因此,例如:-用户希望存储一个新密码:Abc123! - The web application then transforms the given password into 'gibberish': 234fohj234]j8924] (or something similar) and stores it into the db. -然后,Web应用程序将给定的密码转换为“乱码”:234fohj234] [j8924](或类似名称)并将其存储到db中。 - When the user opens the web application to look at his stored passwords, he sees the correct password: Abc123! -当用户打开Web应用程序查看其存储的密码时,他会看到正确的密码: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. -但是,当MySQL管理员使用PHPMyAdmin之类的程序查看/维护数据库时,他只会看到“乱码”密码,而不是真正的密码。

Does PHP (or MySQL) offer a build-in function for something like this? PHP(或MySQL)是否为此类功能提供内置功能? Or does anyone have any tips on creating a function to accomplish this? 还是有人对创建函数来实现此目标有任何提示?

PHP offers the MCrypt library to use two-way encryption. PHP提供了MCrypt库以使用双向加密。 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. 注意不要使用ECB模式进行加密,相同的密码将始终产生相同的密文,而是使用另一种带有随机IV矢量的模式。 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. 由于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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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