我的发展分为两个部分:
ldd --version
回答 EGLIBC 2.15-0ubuntu10.4 2.15 (也许我需要2.7?但在正确升级包时,apt-get
是真正的PAIN。)crypt.h
标题文件提及 @(#)crypt.h 1.5 12/20/96 我的问题出现在身份验证模块中:我无法获得与Symfony的FOSUserBundle生成的哈希相同的哈希值。这是我的例子:
bcccy6eiye8kg44scw0wk8g4g0wc0sk
。test
有了这些信息,Symfony会存储最终的哈希值:
fH5vVoACB4e8h1GX81n+aYiRkSWxeu4TmDibNChtLNZS3jmFKBZijGCXcfzCSJFg+YvNthxefHOBk65m/U+3OA==
现在,在我的C身份验证模块中,我运行了这段代码(包括crypt.h
):
char* password = "test";
char* salt = "$6$bcccy6eiye8kg44scw0wk8g4g0wc0sk";
char* hash = malloc(256);
memset(hash, 0, 256);
encode64(crypt(password, salt), hash, strlen(password));
fprintf(stdout, "%s\n", hash);
(这是我的base64编码器:http://libremail.tuxfamily.org/sources/base64-c.htm)
这就输出......
JDYkYg==
这与我的Symfony2哈希完全不同。
浏览Stack Overflow,我发现这个问题(Symfony2 (FOSUserBundle) SHA512 hash doesn't match C# SHA512 hash)是由遇到同样问题的人编写的(尽管有C#)。所以我决定运行这个测试...
char* password = "test{bcccy6eiye8kg44scw0wk8g4g0wc0sk}";
char* salt = "$6$bcccy6eiye8kg44scw0wk8g4g0wc0sk"; // I tried without salt, or with "$6$" as well.
char* hash = malloc(256);
memset(hash, 0, 256);
encode64(crypt(password, salt), hash, strlen(password));
fprintf(stdout, "%s\n", hash);
当然,这完全失败了,我得到了:
JDYkYmNjY3k2ZWl5ZThrZzQ0cyRycmN6TnpJUXFOYU1VRlZvMA==
我尝试过以各种方式混合密码和盐,但我永远无法在身份验证模块中获得Symfony的盐。在路上有什么我错过的吗?我误解了Symfony的FOSUserBundle存储密码的方式吗?
答案 0 :(得分:4)
不是真正的答案,但我猜你没有研究过Symfony如何对密码进行任何细节编码?编码过程隐藏在编码器对象中。对于SHA512,我们使用:
namespace Symfony\Component\Security\Core\Encoder;
class MessageDigestPasswordEncoder extends BasePasswordEncoder
{
/**
* Constructor.
*
* @param string $algorithm The digest algorithm to use
* @param Boolean $encodeHashAsBase64 Whether to base64 encode the password hash
* @param integer $iterations The number of iterations to use to stretch the password hash
*/
public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000)
{
$this->algorithm = $algorithm;
$this->encodeHashAsBase64 = $encodeHashAsBase64;
$this->iterations = $iterations;
}
public function encodePassword($raw, $salt)
{
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
$salted = $this->mergePasswordAndSalt($raw, $salt);
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; $i++) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
public function isPasswordValid($encoded, $raw, $salt)
{
return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
protected function mergePasswordAndSalt($password, $salt)
{
if (empty($salt)) {
return $password;
}
if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {
throw new \InvalidArgumentException('Cannot use { or } in salt.');
}
return $password.'{'.$salt.'}';
}
正如您所看到的,一个直接问题是默认情况下哈希重复5000次。这个(以及其他输入都可以在app / config / security.yml文件中调整)。
您还可以查看salt和密码合并在一起的位置。这解释了其他stackoverflow的答案。
使用symfony命令从symfony控制台运行此编码算法进行测试将是微不足道的。之后只是调整输入或调整C代码直到结果匹配的问题。
如果你很幸运,那么你所要做的就是添加迭代循环。