我正在使用PEAR :: Mail向我们的客户发送大量电子邮件。我希望能够使用不同的SMTP帐户发送这些电子邮件(因为邮件类型不同)。我们有6-7个帐户,将来可能会有更多。它们中的每一个都有不同的密码,我们希望能够将这些密码存储在数据库中,因此它不是硬编码的,因此您可以使用管理员面板更轻松地添加它们。
我知道我想使用加密来存储密码,但是imo哈希在这里不是一个选项。我希望能够读取这些密码,而不仅仅是比较哈希值。
我想将加密密码存储在数据库中,但使用某种算法加密它们。这就是我遇到问题的地方 - 我对此并不了解。我正在附加我的加密测试代码,但我希望你对如何改进它的意见:
if (!function_exists('hex2bin')) {
function hex2bin($data) {
$len = strlen($data);
return pack('H' . $len, $data);
}
}
$key = $_GET['key'];
$text = $_GET['text'];
$encr = $_GET['encr'];
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
if ($text != null) {
echo bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv));
}
if ($encr != null) {
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, hex2bin($encr), MCRYPT_MODE_ECB);
}
答案 0 :(得分:1)
ECB模式不安全,此模式忽略IV。你应该真的使用CBC(MCRYPT_MODE_CBC)。
使用CBC时,加密需要IV,解密需要相同的IV,因此您需要保持此值(但不要使用相同的IV进行所有加密/解密,生成随机的在你的代码示例中是正确的)。 IV不需要安全存储(比加密数据更安全),并且标准操作是将IV添加到加密数据中。
bin2hex($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv));
解密时,剥离IV并将其传递给mcrypt_decrypt。
$cipherTextDecoded = hex2bin($encr);
$iv = substr($cipherTextDecoded, 0, $iv_size);
$cipherText = substr($cipherTextDecoded, $iv_size);
mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $cipherText, MCRYPT_MODE_CBC, $iv);
另请注意,您应该使用二进制密钥。 $_GET['key']
返回一串文本,因为你不是十六进制解码,你的键空间仅限于所有可能的256位字符串而不是所有256位二进制值。
此外,它在PHP中有点误导,但MCRYPT_RIJNDAEL_256
中的256是指块大小,而不是加密的强度。如果要使用256位加密,只需将256位密钥传递给mcrypt
函数即可。如果这是您的目标,我会考虑使用MCRYPT_RIJNDAEL_128
,这将使加密文本与AES-128兼容。如果您需要在其他系统中解密数据(我不太可能知道),那么找到比Rijindael 256更好的AES-128补充方法。
答案 1 :(得分:0)
我创建了一个类,它可以完成Syon所提到的所有内容。我将它附在此处供将来参考,如果有人想使用它,那么请随意。
<?php
if (!function_exists('hex2bin')) {
function hex2bin($data) {
$len = strlen($data);
return pack('H' . $len, $data);
}
}
/**
* Encipherer - Class used for encoding and decoding
*
* @author kelu
* @version $Id$
*
*/
class Encipherer {
private $key;
private $iv_size;
private $mode = MCRYPT_MODE_CBC;
private $algorithm = MCRYPT_RIJNDAEL_256;
private $rand = MCRYPT_RAND;
/**
* returns singleton
*
* @return Encipherer
*/
public static function Instance()
{
static $inst = null;
if ($inst === null) {
$inst = new Encipherer;
}
return $inst;
}
private function __construct($key = '') {
$this->iv_size = mcrypt_get_iv_size($this->algorithm, $this->mode);
$this->key = $this->key = hex2bin($key);
}
private function __clone()
{
return Encipherer::Instance();
}
public function setKey($key) {
$this->key = $this->key = hex2bin($key);
}
public function encrypt($text) {
$iv = mcrypt_create_iv($this->iv_size, $this->rand);
return bin2hex($iv . mcrypt_encrypt($this->algorithm, $this->key, $text, $this->mode, $iv));
}
public function decrypt($text) {
$cipherTextDecoded = hex2bin($text);
$iv = substr($cipherTextDecoded, 0, $this->iv_size);
$cipherText = substr($cipherTextDecoded, $this->iv_size);
return mcrypt_decrypt($this->algorithm, $this->key, $cipherText, $this->mode, $iv);
}
}
?>
使用示例:
<?
$enc = Encipherer::Instance();
$enc->setKey('1234qwerty');
$encrypted = $enc->encrypt('secret message');
$decrypted = $enc->decrypt($encrypted);
?>