存储用于向PHP客户发送邮件的电子邮件帐户数据的最佳方法是什么?

时间:2013-08-29 14:23:39

标签: php encryption sendmail

我正在使用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);
}

2 个答案:

答案 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);
?>