最好的方式来使用PHP进行加密和解密的密码?[重复]
-
18-09-2019 - |
题
可能的重复:
PHP2方式加密:我需要密码存储,可以将检索到的
我的计划,以储存外国账户的信息对于我的用户在网站上,aka抱歉用户名和密码等。我想保持信息安全,但我知道如果我散他们的信息,我不可以检索它,供以后使用。
Base64是解密,能够使有没有点使用,只是普通关闭。我的想法是争夺的用户和通过之前和之后,它得到base64ed这样,即使后进行解密,你得到一些有趣的看文本,如果你尝试,以解密。是否有一个php能接受的价值观,这将使一个独特的争夺一串和德争夺后来当值reinputed?
任何建议?
解决方案
你应该不加密的密码,而不是你应该散他们使用算法如bcrypt. 这个答案,说明如何适当地实施的密码散列在PHP. 仍然,这里是你会怎么加密/解密:
$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces
加密:
$iv = mcrypt_create_iv(
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
MCRYPT_DEV_URANDOM
);
$encrypted = base64_encode(
$iv .
mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
hash('sha256', $key, true),
$string,
MCRYPT_MODE_CBC,
$iv
)
);
解密:
$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
$decrypted = rtrim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
hash('sha256', $key, true),
substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
MCRYPT_MODE_CBC,
$iv
),
"\0"
);
警告:上面的例子加密的信息,但它不进行身份验证的文,以防止篡改。 你应该 不 依赖未加密的安全, ,特别是因为该码作为提供容易受到填补oracle的攻击。
参见:
- https://stackoverflow.com/a/30189841/2224584
- https://stackoverflow.com/a/30166085/2224584
- https://stackoverflow.com/a/30159120/2224584
还有,不只是使用"密码"一个加密钥匙。 加密钥匙是随机的字符串。
echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="
echo "\n";
echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "
其他提示
安全警告:此类不安全。它的使用 Rijndael256-ECB, ,这不是语义上的安全。只是因为"它"并不意味着"很安全"。此外,这条跟踪空间之后,由于没有使用适当的填充。
发现的这类最近,它就像一个梦!
class Encryption {
var $skey = "yourSecretKey"; // you can change it
public function safe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $data;
}
public function safe_b64decode($string) {
$data = str_replace(array('-','_'),array('+','/'),$string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
}
public function encode($value){
if(!$value){return false;}
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
return trim($this->safe_b64encode($crypttext));
}
public function decode($value){
if(!$value){return false;}
$crypttext = $this->safe_b64decode($value);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
return trim($decrypttext);
}
}
和以叫它:
$str = "My secret String";
$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);
echo "$encoded<p>$decoded";
安全警告: 这种代码不是安全的。
工作实例
define('SALT', 'whateveryouwant');
function encrypt($text)
{
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
function decrypt($text)
{
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
$encryptedmessage = encrypt("your message");
echo decrypt($encryptedmessage);
这只会给你的边际保护。如果攻击者可以运行任意代码的应用程序,他们可以获得的密码在完全相同的方式应用程序可以.你仍然可以得到某些保护,以免遭一些SQL注的攻击和错误的db备份,如果你存放秘密的钥匙文件和使用,以加密的方式向该数据库以及解密的出路。但你应该使用bindparams完全避免的问题SQL注射。
如果决定进行加密,则应使用的一些高级别的加密库为这个,或者你 将 获得这是错误的。你将必须拿到钥匙-设置、信息填充和完整性检查的正确,或者所有你的加密切都是没有多大用处。 GPGME 是一个好选择一个例子。Mcrypt是太低的水平,你可能会得到这是错误的。
Securiy警告:这个代码 不安全.除了脆弱的选择-密文的攻击,它的依赖
unserialize()
使它容易受到PHP物注射。
来处理一个string/array我使用这两个职能:
function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
$s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), '+/=', '-_,');
return $s;
}
function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
$s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, '-_,', '+/=')), MCRYPT_MODE_CBC, md5(md5($key))), "\0"));
return $s;
}
它是灵活的,作为在你可以储存/发送通过URL一串或阵列,因为string/array是serialzed之前加密。
检查mycrypt(): http://us.php.net/manual/en/book.mcrypt.php
如果你使用postgres有pgcrypto数据库级别的加密。(使其更易于搜索和排序)
最好的办法来加密/解密数据库中的数据,即使你已经访问代码是使用2种不同的通行证的私人密码(user-pass
)为每个用户和私人码为所有用户(system-pass
).
方案
user-pass
存储md5在数据库和正在使用验证每个用户登录到系统中。这个用户通的是 不同的 对于每个用户。- 每个用户的数据库中的条目有一md5
system-pass
为加密的数据。这个系统-通过是的 同 对于每个用户。 - 任何时间,用户从系统中删除所有数据都是加密的在旧制度下通必须再次加密在新系统通过避免安全问题。