我需要创建一个与Symfony 3 encodePassword相同的javascript哈希算法。
这是一个类似的问题,但在symfony3:Symfony2 password encoder function in Javascript
这是创建一个消息摘要,用Symfony中的wsse头来测试一个休息终点,并在postman中使用fosbundle。
我已经设法在PHP中简化和复制Symfony哈希函数
$pass = "hello";
$salt = "";
$iterations=5000;
echo $this->encoder->encodePassword($pass,$salt);
//contains: U5xyFq7KQU1CWeX3UcLB0mwWZZQUq0PL8U+GLWomfGW/WQWxxGLi+0ifhmnlw/gQ5pPjNNZV1/q8kMVpAXsFZw==
//simplyfying and replicating the hashing algo in php with same pass/salt:
$salted = $pass.$salt;
$digest = hash("sha512", $salted, true);
for($i=1; $i<$iterations; $i++) {
$digest = hash("sha512", $digest.$salted, true);
}
echo base64_encode($digest);
//contains: U5xyFq7KQU1CWeX3UcLB0mwWZZQUq0PL8U+GLWomfGW/WQWxxGLi+0ifhmnlw/gQ5pPjNNZV1/q8kMVpAXsFZw==
但尝试使用CryptoJS在javascript中复制它是一个麻烦。我怀疑它也与字符编码有关。
根据https://code.google.com/archive/p/crypto-js/#The_Hasher_Input
哈希算法接受字符串或CryptoJS.lib.WordArray [32]字数组的实例。传递字符串时,它会自动转换为编码为UTF-8的WordArray。
password = 'hello';
//attempt 1 use hex converted pass
hexpass = CryptoJS.enc.Utf8.parse(password);
digest = CryptoJS.SHA512(hexpass);
for (i = 1; i < 5000; ++i) {
hexvar = CryptoJS.SHA512(digest + hexpass);
}
digest = digest.toString(CryptoJS.enc.Base64);
console.log(digest);
// need hash to contain: U5xyFq7KQU1CWeX3UcLB0mwWZZQUq0PL8U+GLWomfGW/WQWxxGLi+0ifhmnlw/gQ5pPjNNZV1/q8kMVpAXsFZw==
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
我已经尝试了许多不同的方法来转换到字阵列首先等,但似乎没有相同的哈希
https://jsfiddle.net/munkiepus/awdoq4kL/34/
编辑:我认为问题是PHP使用某种形式的原始二进制文件
将$digest = hash("sha512", $salted, true);
的结果输出到终端显示:
▒q▒$▒b▒x]▒▒j▒▒=s1▒▒�▒▒▒▒▒%g <▒##▒▒▒|z▒n▒▒▒FcG.:▒▒os▒▒▒ C
所以也许在JS中它是不可能的。如果在每次迭代期间将摘要编码为可读字符串,则可能如链接示例中那样。
你为什么需要那个?最好的事情是你只在一侧加密它,无论是从JS还是Symfony,只比较哈希。
另一种选择是不使用encodePassword()
并使用md5()
作为例子。
在这个link向您展示它是如何工作的encodePassword()
。
问候!
好的,这是导致问题的二进制数据,如果我们将单词数组转换为二进制数据库就行了。
需要一些其他函数来进行转换,请参阅函数的runnable示例。例
hashWordArray = CryptoJS.SHA512(password);
uint8array = convertWordArrayToUint8Array(hashWordArray);
binaryString = convertUint8ArrayToBinaryString(uint8array);
for (var i=1; i<5000; i++) {
wordArrayFromString = CryptoJS.enc.Latin1.parse(binaryString+password);
hashWordArray = CryptoJS.SHA512(wordArrayFromString);
uint8array = convertWordArrayToUint8Array(hashWordArray);
binaryString = convertUint8ArrayToBinaryString(uint8array);
}
b64_encoded = btoa(binaryString);
const password = "hello";
// set up the container to display output
var div = document.getElementById('message');
div.innerHTML += 'string to hash:<br>';
div.innerHTML += password+'<br><br>';
div.innerHTML += 'php generated hash:<br>';
correct_hash = 'U5xyFq7KQU1CWeX3UcLB0mwWZZQUq0PL8U+GLWomfGW/WQWxxGLi+0ifhmnlw/gQ5pPjNNZV1/q8kMVpAXsFZw=='
div.innerHTML += correct_hash+'<br><br>';
//actually do the hashing
hashWordArray = CryptoJS.SHA512(password);
uint8array = convertWordArrayToUint8Array(hashWordArray);
binaryString = convertUint8ArrayToBinaryString(uint8array);
for (var i=1; i<5000; i++) {
wordArrayFromString = CryptoJS.enc.Latin1.parse(binaryString+password);
hashWordArray = CryptoJS.SHA512(wordArrayFromString);
uint8array = convertWordArrayToUint8Array(hashWordArray);
binaryString = convertUint8ArrayToBinaryString(uint8array);
}
b64_encoded = btoa(binaryString);
// add the outputr to the display container
div.innerHTML += 'javascript generated hash:<br>';
div.innerHTML += b64_encoded +"<br><br>"; //b64_encode()
// functions from
// https://gist.github.com/getify/7325764
function convertWordArrayToUint8Array(wordArray) {
var len = wordArray.words.length,
u8_array = new Uint8Array(len << 2),
offset = 0, word, i
;
for (i=0; i<len; i++) {
word = wordArray.words[i];
u8_array[offset++] = word >> 24;
u8_array[offset++] = (word >> 16) & 0xff;
u8_array[offset++] = (word >> 8) & 0xff;
u8_array[offset++] = word & 0xff;
}
return u8_array;
}
function convertUint8ArrayToBinaryString(u8Array) {
var i, len = u8Array.length, b_str = "";
for (i=0; i<len; i++) {
b_str += String.fromCharCode(u8Array[i]);
}
return b_str;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<div id="message"></div>