作为练习,我在C ++中编写了自己的SHA-512哈希函数实现。我知道它有效,因为从abc
我得到了
3a81oZNherrMQXNJriBBMRLm.k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw==
在Base64中。就像测试网站一样。
我有两个问题:
如何加密我的密码?如果我有:
string salt = "ssssssss";
string pass = "mysecretpassword";
我应该创建输入字符串作为salt + pass =" ssssssssmysecretpassword"?或者反过来?我试图在谷歌的每个地方找到答案 - 我找不到真正合适的东西。
我应该使用base64中的哪些编码来获取/ etc / shadow文件中的精确哈希密码?
答案 0 :(得分:2)
1)如果散列方案是好的,无论是预先添加还是附加盐,它在安全性方面都没有区别。仅当您想要匹配其他一些已定义的密码哈希过程的结果时。
2)/etc/shadow/
不包含盐+密码的SHA-512哈希这么简单的东西。散列函数的一个应用是通常不足以进行密码散列,这是一种需要矫枉过正的情况。
我相信任何基于GNU的系统都会使用crypt(3)
和glibc支持的其他算法之一。 Wikipedia表示默认使用5000轮SHA-512,但没有提到盐的使用位置。在所有这些轮次之后,最后一个字符串是哈希的base-64编码。您需要深入了解crypt
所做的详细信息,而不是手册页中介绍的内容。您还需要在开始时检查数字,看看算法是否是SHA-512,或其他选项之一。
[编辑:我发现a description of an SHA-512 crypt algorithm但我不知道这是他们实际执行的表单还是仅仅是提案。]
其他* nix系统将拥有自己的等价物,不一定使用相同的散列函数或相同的整体算法。
散列5000次的基本原因是,这意味着访问散列密码的攻击者只能使用给定的处理能力测试1/5000个候选密码。与此同时,您的系统只能对1/5000的登录尝试进行身份验证,但这并不是一个有害的限制(实际上在某些情况下系统会限制登录尝试的速度,因此它基本上没有区别)。
答案 1 :(得分:0)
理论上,将盐(非秘密数据)预先添加到密码(秘密数据)是不好的。因为,由于散列函数按顺序处理它们的输入(以1到64个字节或更多的块为单位),因此可以为非机密数据的初始块预先计算散列函数状态,并将其用作所有未来排列的起点, - 有效去除盐可能引入的几乎任何额外保护。但是,实际上,salt +密码通常占用的密码散列函数(通常为512位或更多)的单个输入块少于一个,因此这不是一个问题。
更重要的是,在加密方面,你不应该发明自己的轮子,而是尽可能使用已有的安全方案。当你问自己:“我应该这个,还是我应该那个?”(比如“我应该先加盐还是加盐?”) - 你的机会很高正在发明一种轮子,这会给你一种虚假的安全感。
通过“腌制密码”的任务,可以采取的一条方法是基于哈希的消息身份验证代码(HMAC)方案,也称为密钥哈希< / strong>:只需将您的salt用作消息,将密码用作密钥 - 该函数将以正确的方式组合参数,从而减轻您记住“是否有责任”的责任前置或附加“。这个函数实际上是常规散列函数的包装器,非常简单,所以如果你的加密框架缺少一个,你可以自己轻松实现它,但一定要测试已知的结果。
另一种可能的选择是基于密码的密钥派生函数,如PBKDF2,它是HMAC或类似函数的另一个包装器。 PBKDF2的一个重要好处是它可以执行几千次散列而不是一次散射,这可能会随着处理能力的提高而增加。
PS。你做了解盐必须在每种情况下随机选择,而不是保持静态(或者更糟糕的是,字典词),是吗?