我正在测试codeigniter加密库,似乎无法获得一致的结果。 我设置了一个测试页面,基本上只有以下代码
$pwd = "test string";
$key = "testkey_obviously_it_will_be_more_secure";
for ($i=0; $i<11; $i++){
echo $this->encrypt->encode($pwd, $key)."<br>";
}
输出是10个完全不同的字符行。
我显然做错了什么,但我看不出它可能是什么。我尝试使用带有和没有$ key的编码功能,但结果对我来说是一样的。
顺便说一下,我在我的测试环境中使用codeigniter 2.1.0
答案 0 :(得分:3)
编码库按预期工作。我们来看看默认的mcrypt_encode()方法:
function mcrypt_encode($data, $key)
{
$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
$init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);
}
请注意编码内发生的随机因素,并将噪声添加到加密中。尝试将您生成的10个密钥存储到一个数组中并对其进行解密。你会正确地恢复你的价值。
如果您正在寻找严格单向编码并产生一致的结果,我建议在PHP中使用hash()方法(从5.1.2开始提供):http://www.php.net/manual/ro/function.hash.php
生成哈希值的一种安全方法是创建一个随机种子值,然后将其连接到用户的密码。这可以防御彩虹表破解和其他事情。
hash('sha512', $seed . $password);
更新:我们的想法是使用加密类以便能够对某些字符串进行编码并还解码。可以这样想想 - 它不是一个安全的例子,但它可以帮助理解这一点:你想在你的网站上存储一个人的信用卡信息。当然,您希望保持这些信息的安全,这样如果有人闯入您的数据库,这并不是一件大事,因为所有这些信息都是加密的。您当然也希望能够解码该信息并将其显示给用户,以防他们再次从您的网站订购某些内容,而不是让他们手动输入数据,因此您还需要能够解密该数据。
一般来说,根据经验,我的理解是,如果加密算法是双向的(也就是说,它可以被编码和解码),那么它就不如单向加密算法那么安全(只编码数据)。
如果您正在存储用户登录凭据,您将永远不希望能够解码用户的密码,例如,因为这是用户可以轻松重置的内容。您永远不想在帐户上显示用户密码,因此您始终将其牢牢锁定。这是您使用单向加密算法的地方 - 您在创建条目时对数据进行一次编码,然后在数据库中查找条目时,而不是运行以下内容:
SELECT *
FROM user
WHERE user.password = 'STAR_WARS'
您可以运行类似:
SELECT *
FROM user
WHERE user.password = '5badcaf789d3d1d09794d8f021f40f0e'
上述方法可以通过编码您第一次从用户那里收到的数据进行编码,当您设置帐户时,然后无论何时检查登录凭据,您只需运行编码算法他们提供的字符串。
作为创建新帐户的工作流程:
验证用户的工作流程:
在上述系统中,我们从不存储用户的原始密码 - 仅存储加密数据。
现在这本身看起来很简单,但是作为加密算法的MD5已经完全破解 - 也就是说,因为只有很多字符串组合可能,大多数值都被反转,所以黑客取值'5badcaf789d3d1d09794d8f021f40f0e '并且他们通过一个脚本运行它,列出可能的登录密码,这些密码都映射到'5badcaf789d3d1d09794d8f021f40f0e',其中我们也会找到'starwars'。
重要的是让密码生成尽可能长或模糊,但尽可能随机。这就是为什么在上面的例子中,我们生成一个种子,我们用它来为密码添加一个随机元素,我们使用更强大的加密算法。
所以种子可能是字符串:'sajuh27ahjs'。
当用户创建新帐户时,我们会将种子与其原始密码连接起来。因此,对于我们的星球大战示例,用户在加密之前的原始密码将是:
'sajuh27ahjsstarwars'
种子存储在数据库中,没有加密,很明显,因为我们稍后需要解码。好的,现在我们用强大的东西加密密码,比如SHA512。因此我们得到:
hash('sha512', $seed . $password);
注意这种攻击很难打破,因为种子添加了一个随机元素,这使得破坏者很难理解我们放置种子的位置,即使有了这些知识,也需要建立一个表格。可以生成的每个特定随机种子的值映射(很多)。
希望清除一些东西,随意拍出更多问题!