首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PHP存储用于向客户发送邮件的电子邮件帐户数据的最佳方法是什么?

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

Stack Overflow用户
提问于 2013-08-29 14:23:39
回答 2查看 80关注 0票数 0

我用PEAR::邮件发送了大量的电子邮件给我们的客户。我希望能够使用不同的SMTP帐户发送那些电子邮件(因为不同的邮件类型)。我们有6-7个账户,将来可能会有更多的账户。它们中的每一个都有不同的密码,我们希望能够将这些密码存储在数据库中,这样就不会硬编码,因此您可以更容易地使用管理员面板添加它们。

我知道我想使用加密来存储密码,但是imo哈希不是一个选项。我希望能够读懂那些密码,而不仅仅是比较哈希。

我想在数据库中存储加密的密码,但是使用一些算法来加密它们。这也是我遇到问题的地方--我对此不太了解。我正在附加用于加密的测试代码,但我希望您对我应该如何改进它的意见:

代码语言:javascript
复制
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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-29 15:32:56

欧洲央行模式是不安全的,这种模式忽略了IV。您应该使用CBC (MCRYPT_MODE_CBC)代替。

当使用CBC时,加密需要使用IV,解密需要使用相同的IV,因此您需要保留这个值(但是在所有加密/解密中不要使用相同的IV,生成一个随机的IV,就像代码示例中的正确一样)。IV不需要安全地存储(比加密的数据更安全),它的标准过程是将IV添加到加密的数据中。

代码语言:javascript
复制
bin2hex($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv));

解密时,您可以去掉IV并将其传递给mcrypt_decrypt。

代码语言:javascript
复制
$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兼容。如果您需要解密其他系统中的数据(我不太可能知道),那么要找到AES-128 imeplementation比Rijindael 256容易得多。

票数 1
EN

Stack Overflow用户

发布于 2013-08-30 12:02:29

我创建了一个类,它完成了Syon提到的所有事情。我把它附在这里,以供将来参考,如果有人想使用它,那就放心吧。

代码语言:javascript
复制
<?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);
    }
}

?>

示例用法:

代码语言:javascript
复制
<?
$enc = Encipherer::Instance();
$enc->setKey('1234qwerty');
$encrypted = $enc->encrypt('secret message');
$decrypted = $enc->decrypt($encrypted);
?>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18513602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档