JavaScript在sha512中加密并获得原始二进制数据的结果,如PHP hash()

时间:2014-10-28 18:49:24

标签: javascript symfony hash

正如我在标题中所说,我需要重现这个PHP函数(在JavaScript中):

hash("sha512", "string", true);

棘手的部分,如果最终的真实意味着:

  

设置为TRUE时,输出原始二进制数据。 FALSE输出小写   hexits。

如果我需要自己创造一些东西并且我应该照顾这个结尾,这也很重要:

  

老虎算法现在使用大端字节排序。

参考:php.net - hash()

编辑:经过一些测试和研究,这里是我需要在javascript中重现的功能:

hex2bin("string");

其实巫婆CryptoJS我能够以六进制获得结果。我不知道如何在行二进制数据(相当于hex2bin)中获取它。

我发现使用NodeJS和库加密我们可以很容易地做到这一点,但我不使用NodeJS。我需要在经典JavaScript(或jQuery或任何其他可以工作的lib)中获得相同的结果。

我的目标是向Symfony的WSSE协议发送一个与数据库中的密码匹配的密码(passwordDigest)。

这是我需要重现的PHP代码:

public function encodePassword($raw, $salt)
    {

        // ... Some check code for data

        $salted = $this->mergePasswordAndSalt($raw, $salt); // Just do $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);
    }

以下是我实际拥有的JavaScript代码:

WSSE.encodePassword = function(password, salt) {
    try {
        var salted = WSSE.mergePasswordAndSalt(password, salt);
        var digest = CryptoJS.SHA512(salted).toString();

        for (i = 1; i < 5000; i++) {
            digest = CryptoJS.SHA512(digest + salted).toString();
        }

        return WSSE.base64_encode(digest);
    } catch(err) {
        Log.e("WSSE", err.message);
        return null;
    }
};

此代码的问题在于摘要变量始终包含六进制数据,而不是原始二进制数据。

每个人的想法,代码还是lib?

PS:对不起,如果有错误,英语不是我的母语。

2 个答案:

答案 0 :(得分:2)

我找到了一个解决方案,基于EmberJS的WSSE实现:https://github.com/Gerfaut/ember-simple-wsse-auth

正好在https://github.com/Gerfaut/ember-simple-wsse-auth/blob/master/packages/ember-simple-wsse-auth/lib/core.js

Ember.SimpleWsseAuth.EncodePassword = function(password, salt) {
    var salted = password + '{' + salt + '}';
    var passwordEncoded = CryptoJS.SHA512(salted);
    for(var i = 1; i < this.passwordEncodingIterations; i++) { //TODO use webworker
        passwordEncoded = CryptoJS.SHA512(passwordEncoded.concat(CryptoJS.enc.Utf8.parse(salted)));
    }
    return this.passwordEncodingAsBase64 ? passwordEncoded.toString(CryptoJS.enc.Base64) : passwordEncoded;
};

您的encodePassword函数变为

WSSE.encodePassword = function(password, salt) {
    try {
        var salted = WSSE.mergePasswordAndSalt(password, salt);
        var digest = CryptoJS.SHA512(salted);

        for (i = 1; i < 5000; i++) {
            digest = CryptoJS.SHA512(digest.concat(CryptoJS.enc.Utf8.parse(salted)));
        }    

        return WSSE.base64_encode(digest);
    } catch(err) {
        Log.e("WSSE", err.message);
        return null;
    }
};

答案 1 :(得分:0)

使用 http://movable-type.co.uk/scripts/sha512.html 可以获得与使用函数相同的输出

hash('sha512', 'puma');

这是来自 Chris Veness

的出色解决方案