c - C 中的 Salted sha512,无法与 Symfony2 的 FOSUserBundle 同步

标签 c symfony fosuserbundle sha512

我的开发分为两个部分:

  • 网站、使用 FOSUserBundle 的 Symfony 应用程序(使用 SHA512 加密密码)和盐。
  • 一个用 C 语言编程的身份验证模块,一旦给出盐和明文密码,它应该能够重现 SHA512 加盐哈希。

有关我的环境的一些信息

  • 我使用的是 Linux Ubuntu 12.04。
  • ldd --version 回答 EGLIBC 2.15-0ubuntu10.4 2.15 (也许我需要 2.7?但是 apt-get 是一个真正的痛苦当涉及到正确升级软件包时)。
  • crypt.h 头文件提到 @(#)crypt.h 1.5 12/20/96

问题本身

我的问题出现在身份验证模块中:我无法获得与 Symfony 的 FOSUserBundle 生成的哈希值相同的哈希值。这是我的例子:

  • Symfony 使用的密码盐是 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 存储密码的方式?

最佳答案

这并不是一个真正的答案,但我猜你还没有详细研究过 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 文件中调整)。

您还可以看到盐和密码合并在一起的位置。这解释了其他 stackoverflow 答案。

创建一个 symfony 命令来从 symfony 控制台运行此编码算法进行测试是很简单的。之后,只需调整输入或调整 C 代码直到结果匹配即可。

如果你幸运的话,那么你所要做的就是添加迭代循环。

关于c - C 中的 Salted sha512,无法与 Symfony2 的 FOSUserBundle 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18289472/

相关文章:

c - C语言%运算符和google计算器mod的区别

c - 如何使用 void 修改链表节点?

c - 在 C 中打印字符串数组的元素

symfony - 删除 FOSUserBundle 错误消息

php - 在 Symfony 的 FOSUserBundle 中检测重复登录

c++ - 如何将两个正整数映射到一个唯一的整数?

Symfony2 - 可翻译字段 - 在链配置的命名空间中找不到类 'Gedmo\Translatable\Entity\Translation'

symfony - 存储上传文件的最安全方式

php - 如何测试对象是否持久保存在数据库 Symfony/PHPUnit 中

php - 无限循环存储库 symfony2 fos 用户包