我实现了一个简单的gode,用于使用Go确定性生成密码,使用this scrypt实现。我的code is here,这是对相关部分的提取:
const keyLen = 8
// recommended cost parameters for interactive login in 2009
const N = 16384
const r = 8
const p = 1
func main() {
dk, _ := scrypt.Key([]byte("mypassword"), []byte("mysalt"), N, r, p, keyLen)
for _, v := range dk {
fmt.Printf("%x ", v)
}
fmt.Println()
}
运行代码我得到输出:
19 e5 59 39 fe 1 2b ef
然而,当我尝试基于libscrypt的C实现时,我会 NOT 获得相同的输出。我会得到:
68 56 66 b2 86 19 2f 6e
C代码是here,这是主要部分:
int N = 16384;
int r = 8;
int p = 1;
const int keyLen = 8;
int main(void) {
unsigned char digest[keyLen];
const unsigned char password[] = "mypassword";
const unsigned char salt[] = "mysalt";
libscrypt_scrypt(password, sizeof(password), salt, sizeof(salt), N, r, p, digest, keyLen);
for (int i = 0; i < keyLen; ++i) {
printf("%x ", digest[i]);
}
printf("\n");
return 0;
}
我还遇到了另一个实现scrypt-jane,它在散列时给出了另一个结果。虽然我意识到这可能是因为scrypt jane允许您选择使用哪种散列函数。在任何情况下我都没有使用随机盐。
我试图在这里验证我自己的预感是没有关于scrypt使用散列函数的明确标准。如果是这样,我如何确保Go,C,python或JavaScript中的实现都产生相同的结果?我宁愿避免自己移植代码,因为据我所知,这是密码学中的风险业务。
答案 0 :(得分:6)
在库中调用libscrypt_scrypt
方法的C代码包含两个错误,这会导致计算错误的结果。违规部分是:
sizeof(password)
sizeof(salt)
sizeof
将包括字符串末尾的termnating 0,因此不是“mypassword”和“mysalt”分别得到长度10和6,它们得到11和7.因此计算时包含两个额外的0哈希。
所以问题可以通过写:
来解决strlen((const char *)password)
strlen((const char *)salt)
或
sizeof(password) - 1
sizeof(salt) - 1
表示scrypt
哈希函数的 salt 和密码参数。