【发布时间】:2022-07-26 15:04:30
【问题描述】:
我的目标是使用 NodeJS 创建类似于 slappasswd 命令行工具的 LDAP 密码哈希。
以下是使用命令行生成 LDAP 密码的方法:
slappasswd -h '{SSHA}' -s 'P@ssw0rd'
{SSHA}1RHPt8m4AWLjK8Px1MT6FEBJOBJpdzqT
结果是一个 base64 编码的加盐 SHA1 密码。
这是我最初尝试重新创建的内容:
#!/usr/bin/env node
import sha1 from 'crypto-js/sha1.js';
let password = 'P@ssW0rd';
let salt = btoa(0xA5); // Not random, just a proof of concept temporary value.
let hash = sha1(password + salt);
console.log('{SSHA}' + btoa(hash));
但是,我得到的字符串比 slappasswd 命令生成的要长得多,我不知道为什么。
{SSHA}NDVkN2JjODQ2ZDk3Yjc2YmViNTU3MzUzYjBiNzExN2ZmYzMxYWY5ZA==
我在网上进行了一些挖掘,并在 LDAP 密码生成器网页上找到了这个:
<script src="lib/cryptojs/core.js"></script>
<script src="lib/cryptojs/sha1.js"></script>
<script src="lib/cryptojs/enc-base64.js"></script>
<script>
function slappasswd(password) {
var salt = CryptoJS.lib.WordArray.random(128/8).toString().substr(0,4);
var hash = CryptoJS.SHA1(password + salt);
var base = CryptoJS.enc.Latin1.parse(hash.toString(CryptoJS.enc.Latin1) + salt).toString(CryptoJS.enc.Base64);
return '{SSHA}' + base;
}
...
网页生成的字符串长度与 slappasswd 的长度相同,因此我认为这是对 slappasswd 逻辑的准确再现。
使用这些信息,我的下一次尝试如下所示:
#!/usr/bin/env node
import * as CryptoJS from 'crypto-js';
let password = 'P@ssW0rd';
let salt = CryptoJS.lib.WordArray.random(128/8).toString().substr(0,4);
let hash = sha1(password + salt);
let base = CryptoJS.enc.Latin1.parse(hash.toString(CryptoJS.enc.Latin1) + salt).toString(CryptoJS.enc.Base64);
console.log('{SSHA}' + base);
但是,我得到了错误。
首先是TypeError: Cannot read properties of undefined (reading 'WordArray')
如果我在第一次尝试代码中将 let salt = 替换为 let salt = btoa(0xA5),则会收到错误消息:ReferenceError: sha1 is not defined
我的感觉是我的导入错误。
我正在尝试做相当于var CryptoJS = require("crypto-js"); 的 ES6 模块,但在某处失败了。
所以我的问题有两个:
- 我的第一次尝试是否可以生成一个类似于 slappassword 输出的字符串长度?
- 如果没有,我该如何解决我在第二次尝试中遇到的错误?
理想情况下,我想了解我在第一次尝试时出错的地方,而不是在没有完全掌握的情况下简单地复制和粘贴其他人的代码(第二次尝试)。
【问题讨论】:
标签: javascript node.js cryptojs