哈希机制真的安全吗?
Posted
技术标签:
【中文标题】哈希机制真的安全吗?【英文标题】:is hashing mechanism really secure? 【发布时间】:2012-10-30 15:56:00 【问题描述】:嗯,我一直看到(和关注)人们说要使用散列机制将密码存储在数据库中。我真的很担心它是否安全?
举个例子吧。
假设我是黑客,我得到了您的数据库名称、ID 和密码。现在我可以完全访问您的数据库了。
人们所说的密码应该被散列,因为如果有人入侵,他们就会被黑客看到。
所以如果我以select id, password FROM userDetails
运行查询,我将得到如下数据
选项 1:没有哈希
++++++++++++++++++++++++++++
+ id + password +
++++++++++++++++++++++++++++
+ id01 + password01 +
+ id02 + password02 +
++++++++++++++++++++++++++++
选项 2:使用哈希
++++++++++++++++++++++++++++
+ id + password +
++++++++++++++++++++++++++++
+ id01 + hasValue01 +
+ id02 + hasValue02 +
++++++++++++++++++++++++++++
好吧,我还是要说,散列是不安全的。为什么我会在下面用Java代码告诉你。
PreparedStatement pst = conn.prepareStatement("SELECT id, password FROM userDetails");
ResultSet rs = pst.executeQuery();
String randomPassword = "";
StringBuffer sb;
boolean myPassCheck = true;
while (rs.next())
myPassCheck = true;
while (myPassCheck)
// this will generate random password
randomPassword = generateRandomPassword();
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(randomPassword.getBytes());
sb = new StringBuffer();
for (int i = 0; i < array.length; ++i)
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
if (sb.toString().equals(rs.getString(2)))
// this is password
myPassCheck = false;
System.out.print("id=" + rs.getString(1) + ", password=" + sb.toString());
这样,我可以打印用户名和密码。 (我知道我必须生成随机密码,直到我没有找到密码)。但是这样一来,哈希密码机制也失效了。
我也相信这个世界上存在解密器,它将哈希数据转换为实际数据。
所以我在想
散列机制是否安全?
编辑 1
我说的不仅仅是 MD5。我选择 MD5 仅用于示例目的。我说的是任何安全密码机制
【问题讨论】:
如果不是MD5,那我还应该用什么? @dystroy :如果我能问谷歌先生,我就不会在这里问这个问题了。 安全性不是二进制的。散列更安全。加盐散列更加安全。使用加盐哈希的隔离数据库更加安全...... 3 反对票?我很惊讶......哇哇哇!!! 【参考方案1】:密码永远不会以明文形式存储。至少他们不应该这样,除非你正在使用世界上最天真的程序员构建世界上最不安全的系统。
相反,密码存储为哈希函数的输出。即使攻击者获得了您密码的散列版本的访问权限,也无法仅从散列值重构密码。
但是可以使用彩虹表攻击密码的哈希值:每个可能的字符组合的巨大的、预先计算的哈希值。攻击 PC 肯定可以即时计算所有这些哈希值,但是利用预先计算的大量哈希值表可以使攻击更快地进行几个数量级——假设攻击机有足够的 RAM 来存储整个表(或至少大部分)在内存中。像这样的表称为rainbow table
这是一种经典的时间-记忆权衡,正是您希望黑帽攻击者采取的那种作弊捷径。
以下字符集的数据库:ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+=~[]|\:;"'<>,.?/
最大密码长度为 14 的大小为 64GB。
如果您对密码哈希进行了加盐处理,攻击者就不能对您使用一般的rainbow table
攻击,“密码”和“美味咸密码”的哈希结果将不匹配。除非你的黑客不知何故知道你所有的哈希都是“美味的咸”。
即便如此,他或她也必须专门为您生成自定义彩虹表。
请阅读 Thomas Ptacek 关于此主题的 excellent and informative article。它更详细地介绍了密码哈希的具体细节。
最后是您问题的答案:
不,它不安全,但您可以尽最大努力使其尽可能安全。
【讨论】:
我不同意这一点即使攻击者获得了您密码的散列版本的访问权限,也无法仅从散列值重构密码。。我上面显示了,我怎样才能得到密码。 我还提供了一种方法...使用数据库,比您的解决方案更快... @FahimParkar 您没有说明如何获取密码。您展示了蛮力攻击(即散列每个可能的密码,直到获得匹配的散列)是可能的。但这并不是什么新鲜事——事实上,这并不奇怪。这是唯一可能针对理想的加密安全散列函数的攻击。我建议您阅读 Bruce Schneier 的优秀书籍“应用密码学”,并多了解一下自己。查看:amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/…【参考方案2】:不,仅使用哈希,尤其是仅将 MD5 应用于密码时,并不安全,因为:
如果您只是转换一个密码(通常几乎是一个常用词),那么使用常用密码数据库很容易对其进行测试。所以总是使用盐,最好是用户记录的其他常量部分的组合。有时您甚至可以通过在 Google 中输入哈希来找到哈希的来源... MD5 is prone to collisions,所以即使使用散列,也更喜欢 SHA 256 或更好 MD5 的计算速度很快,在蛮力攻击中测试也很快使用散列机制但是:
取更好的哈希函数,例如SHA-256 or SHA-512 散列一个构造字符串,例如用户名+salt+密码(你可以使用常量盐,只要它不被其他程序使用,对于大多数用途来说已经足够了)注册某人(或某人更改密码)的过程是
1) 将字符串 s 构建为 s=username+salt+password(或类似函数)
2) 将哈希构建为 SHA256(s)
3) 将用户名、salt(如果不是常量)和哈希值存储在数据库中
在验证用户时,您以相同的方式构建散列(使用用户提供的用户名和密码以及您在数据库中的盐)并将用户名和散列与您在数据库中的内容进行比较。你不要反转散列函数,因为那是不可行的。
现在关于您的代码:您的方法似乎是生成所有可能的密码,直到一个具有与您尝试猜测的密码相同的 MD5 为止。 这不适用于合理的密码,因为没有足够的时间来测试 15 个字符的所有组合。
【讨论】:
我认为 SHA-256 或 SHA-512 也不安全。我将通过编辑我的问题来解释为什么。在此之前,让我先阅读您的链接。 :) 我有一个问题:假设我的密码是@p1a2s3s@
& 当我使用 SHA-256 时,我得到的输出为0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
。现在我相信每当我以@p1a2s3s@
向SHA-256 提供输入时,我都会得到0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
的输出。对吗?
我在此评论中没有得到您的问题。 SHA-256 不可逆。
如果不可逆,如何比较我的密码?当我输入我的用户名和密码时,我必须匹配它们
您不会比较用户名和密码:您将对它们进行哈希处理(使用盐)并将哈希值与您存储的哈希值进行比较。【参考方案3】:
不,它们不是 100% 安全的,特别是如果攻击者有哈希数据库。更好的方法是使用加盐密码,因为这会使哈希数据库变得毫无用处。
使密码更安全的另一种方法是对其进行多次哈希处理,这也会降低哈希数据库的有效性。
正如其他帖子所提到的,选择更安全且成本更高的算法,例如 sha-512。
【讨论】:
谢谢,你能给我提供正确的链接吗?salted password
用例子正确解释了吗?
我不确定算法是否也安全。为什么因为如果我生成随机密码并将其提供给 sha-512,它会给我输出类似于 MD5 的输出。从那里我也可以得到密码。所以我相信散列在任何地方都失败了......
感觉的感觉来破解我的密码:9357d8611d03db1c54bb6bae5e9f1bfa857f655e523455593bc474bd67797fa42de4c0b51ef28caa8710bccbfd1ad780d2bf91311d9951c2d18f9cb868015e1c(提示,盐化SHA 512):)跨度>
我有一个问题:假设我的密码是@p1a2s3s@
& 当我使用 SALTE 时,我得到的输出为9357d8611d03db1c54bb6bae5e9f1bfa857f655e523455593bc474bd67797fa42de4c0b51ef28caa
。现在我相信每当我向 SALTE 提供输入时,我都会得到9357d8611d03db1c54bb6bae5e9f1bfa857f655e523455593bc474bd67797fa42de4c0b51ef28caa
的输出。对吗?
希望我能成为黑客......我肯定会破解你的密码。我喜欢玩数据。【参考方案4】:
没有。散列密码并不安全,但比不这样做更安全。如您所见,如果您有足够的时间和硬件资源,此类散列密码可能很容易被解密。这就是为什么我们经常使用盐来使我们的密码更安全。盐是以某种方式与真实密码合并的东西,您存储此类字符串的哈希码。攻击者可能能够破解加密,但他会收到混合了盐的密码。对于使用所谓的“彩虹表”来解密密码的人来说,这是一个很好的保护。不幸的是,它仍然是易碎的。在这里您可以找到更多相关信息:http://arstechnica.com/security/2012/08/passwords-under-assault/
【讨论】:
好的。我的错,你是对的。我不是以英语为母语的人,这就是我使用这个词的原因。以上是关于哈希机制真的安全吗?的主要内容,如果未能解决你的问题,请参考以下文章