我想加密二进制文件.我的目标是防止任何人读取没有密码的文件.
哪个是更好的解决方案,AES或Blowfish具有相同的密钥长度?我们可以假设攻击者拥有破解文件的大量资源(软件,知识,资金).
上周我读了很多关于密码哈希和Blowfish的文章,似乎是(现在)最好的哈希算法之一 - 但这不是这个问题的主题!
Blowfish只考虑输入密码中的前72个字符:
<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);
$input = substr($password, 0, 72);
var_dump($input);
var_dump(password_verify($input, $hash));
?>
Run Code Online (Sandbox Code Playgroud)
输出是:
string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add …
Run Code Online (Sandbox Code Playgroud) 这个问题与PHP的实现有关crypt()
.对于这个问题,盐的前7个字符不计算,所以盐' $2a$07$a
'的长度为1,因为它只有盐的1个字符和元数据的7个字符.
当使用长度超过22个字符的salt字符串时,生成的哈希值没有变化(即截断),当使用短于21个字符的字符串时,盐将自动填充($
显然有' '字符); 这是相当简单的.但是,如果给出20个字符的盐和21个字符的盐,除了21个长度的盐的最终字符外两个是相同的,两个散列字符串都是相同的.一个长22个字符的盐,除了最后一个字符外,它与21个长度的盐相同,哈希值会再次不同.
代码示例:
$foo = 'bar';
$salt_xx = '$2a$07$';
$salt_19 = $salt_xx . 'b1b2ee48991281a439d';
$salt_20 = $salt_19 . 'a';
$salt_21 = $salt_20 . '2';
$salt_22 = $salt_21 . 'b';
var_dump(
crypt($foo, $salt_19),
crypt($foo, $salt_20),
crypt($foo, $salt_21),
crypt($foo, $salt_22)
);
Run Code Online (Sandbox Code Playgroud)
会产生:
string(60) "$2a$07$b1b2ee48991281a439d$$.dEUdhUoQXVqUieLTCp0cFVolhFcbuNi"
string(60) "$2a$07$b1b2ee48991281a439da$.UxGYN739wLkV5PGoR1XA4EvNVPjwylG"
string(60) "$2a$07$b1b2ee48991281a439da2.UxGYN739wLkV5PGoR1XA4EvNVPjwylG"
string(60) "$2a$07$b1b2ee48991281a439da2O4AH0.y/AsOuzMpI.f4sBs8E2hQjPUQq"
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
一些用户注意到整个字符串存在差异,这是正确的.在salt_20
,偏移(28,4)是da$.
,而在salt_21
,偏移(28,4)是da2.
; 但是,重要的是要注意生成的字符串包括散列,盐,以及生成盐的指令(即$2a$07$
); 实际上,差异发生的部分仍然是盐.实际哈希值不变UxGYN739wLkV5PGoR1XA4EvNVPjwylG
.
因此,这实际上并不是产生的散列的差异,而是用于存储散列的盐的差异,这恰恰是手头的问题:两个盐生成相同的散列.
Rembmer:输出将采用以下格式:
"$2a$##$saltsaltsaltsaltsaltsaHASHhashHASHhashHASHhashHASHhash"
// ^ Hash Starts …
Run Code Online (Sandbox Code Playgroud) 1)如何使用crypt()创建安全的Blowfish哈希密码?
$hash = crypt('somePassword', '$2a$07$nGYCCmhrzjrgdcxjH$');
Run Code Online (Sandbox Code Playgroud)
1a)"$ 2a"的意义是什么?它只是表明应该使用Blowfish算法吗?
1b)"07美元"有什么意义?更高的值意味着更安全的哈希吗?
1c)"$ nGYCCmhrzjrgdcxjH $"有什么意义?这是将要使用的盐吗?这应该随机生成吗?硬编码?
2)你如何存储河豚的哈希?
echo $hash;
//Output: $2a$07$nGYCCmhrzjrgdcxjH$$$$.xLJMTJxaRa12DnhpAJmKQw.NXXZHgyq
Run Code Online (Sandbox Code Playgroud)
2a)这应该存储在数据库中的哪一部分?
2b)列应该使用什么数据类型(MySQL)?
3)如何验证登录尝试?
关于设置config.inc.php,官方phpMyAdmin文档说
$cfg['blowfish_secret'] = 'theExampleWrites16ValuesHere'; // use here a value of your choice
Run Code Online (Sandbox Code Playgroud)
什么是河豚的秘密?如何生成或选择值?
我一直在阅读bcrypt
(应用程序视角).考虑使用它来存储我的网站上的密码.
在我阅读的一些内容中,它提出了两种方式:
- 例如1:Bcrypt是来自bcrypt的跨平台文件加密实用程序
- 例如2:bcrypt是一种自适应密码散列算法,它使用Blowfish密钥调度,而不是对称加密算法.从如何安全存储密码
- bcrypt是由Niels Provos和DavidMazières设计的密码自适应加密哈希函数,基于Blowfish密码:来自bcrypt wiki
究竟什么是Bcrypt?
我在理解php的crypt函数方面有点麻烦.我的PHP版本是5.4.7.
我想使用crypt在数据库中存储salted密码,因为据我所知,使用md5哈希密码的开发人员将在现场进行赌注和烧毁.
我想使用blowfish alg来生成哈希.现在,根据php文档,如果用"$ 2y $"+成本(例如:"08")+"$"+ 22个字符盐(./0-9A-Za-z)调用它,则crypt使用blowfish .但是,这一点测试代码的输出让我很困惑:
echo "<pre>";
if (CRYPT_BLOWFISH == 1) {
echo 'Blowfish SaltLen = 18: ' . crypt('string that should be hashed', '$2y$08$123456789012345678') . "\n";
echo 'Blowfish SaltLen = 19: ' . crypt('string that should be hashed', '$2y$08$1234567890123456789') . "\n";
echo 'Blowfish SaltLen = 20: ' . crypt('string that should be hashed', '$2y$08$12345678901234567890') . "\n";
echo 'Blowfish SaltLen = 21: ' . crypt('string that should be hashed', '$2y$08$123456789012345678901') . "\n";
echo 'Blowfish SaltLen = 22: …
Run Code Online (Sandbox Code Playgroud) 我已经阅读了PHP手册输入中crypt()
提供的信息,但我发现自己仍然不确定触发Blowfish算法的salt的格式.
根据手动输入,我应该使用'$ 2 $'或'$ 2a $'作为16个字符串的开头.然而,在以后的例子中,他们使用更长的字符串:" $2a$07$usesomesillystringforsalt$
",这表明,我认为任何字符串我提供将切片和切块以适应模型.
我遇到的问题实际上是触发河豚算法中VS STD_DES
.例:
$foo = 'foo';
$salt = '$2a$' . hash('whirlpool', $foo); // 128 characters, will be truncated
$hash = crypt($foo, $salt);
// $hash = $26HdMTpoODt6
Run Code Online (Sandbox Code Playgroud)
那哈希显然不是漩涡,事实上STD_DES
只有盐的前两个字符用于盐.但是,在PHP手册的例子中,他们的盐以' $2a$07$
' 开头,所以如果我将这三个字符添加到相同的代码中,我得到以下内容:
$foo = 'foo';
$salt = '$2a$' . hash('whirlpool', $foo); // 128 characters, will be truncated
$hash = crypt($foo, $salt);
// $hash = $2a$07$b1b2ee48991281a439da2OHi1vZF8Z2zIA.8njYZKR.9iBehxLoIC
Run Code Online (Sandbox Code Playgroud)
我发现我可以提供在此处显示为"人物存在一些差异07$
",例如04$
和15$
两个工作,但01$
通过03$
不工作(生成一个空字符串),和值等99$
,并85$ …
PASSWORD_DEFAULT和PASSWORD_BCRYPT有什么区别?他们都使用Blowfish加密算法吗?算法的成本是多少?如何在PHP中设置password_hash产生255哈希长度而不是60?