如何解决如何在C和ubuntu中使用salt加密SHA512哈希?
我正在尝试用salt加密哈希。
在命令行中,我发现使用下面的命令将正确的哈希写入影子文件中。
openssl passwd -6-盐abcd适用 $ 6 $ abcd $ vIWAp1OzuGuo376cRkZ5DXcgI8KIlnUibsk.iydtfCFqb9okOz.S70Ysu7.qRRg9Me5XwAyTjkZBQJXiIxwpL /
然后我尝试使用openssl(How to convert a raw 64-byte binary to Hex or ASCII in C)在C语言中获取它。
#include <openssl/sha.h>
#include <stdio.h>
#include <string.h>
int main() {
char data[] = "abcdapple";
unsigned char hash[SHA512_DIGEST_LENGTH*2+1];
SHA512((unsigned char *)&data,strlen(data),(unsigned char *)&hash);
char buffer[SHA512_DIGEST_LENGTH*2+1];
for(int i =0; i < SHA512_DIGEST_LENGTH; ++i)
sprintf(&buffer[i*2],"%02x",(unsigned int)hash[i]);
printf("digest: %s\n",buffer);
printf("\n");
}
但是生成的哈希是ea1d5a8b11297d20f954a3ab15092d21b733484b2eb9b7226b2b138639f0df30627774945458a774eb279cd279d83d2e977a2bc5599606d6a9a3b2f075f9b1895ecd,与正确的事物不同。
我认为我用盐不好。似乎也存在根本问题。 我不能使用C盐实现加密程序吗?
解决方法
您尝试生成的不是普通的SHA-512哈希。这是使用基于SHA-512的专用算法的散列密码。 openssl passwd
计算该算法,但是OpenSSL库的SHA512
函数计算普通的SHA-512。 crypt(5) manpage中记录了这种专用算法以及其他具有相同功能的算法。
您可以可能使用crypt_r
库中的libcrypt
函数(由于历史原因,该库的名称不正确;仅 提供密码哈希算法),以使用与openssl passwd
相同的专用算法来计算哈希密码。在我的计算机上,该程序会以您得到的$6$abcd
开头打印相同的字符串:
#include <crypt.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
struct crypt_data cd;
memset(&cd,sizeof cd);
puts(crypt_r("appple","$6$abcd",&cd));
return 0;
}
请注意第二个参数(在我一直链接到的文档中称为“设置字符串”)如何同时包含盐值abcd
和前缀$6$
(它告诉{{ 1}}使用基于SHA-512的哈希)。它的工作方式是,crypt_r
可以使用刚从tty读取的密码作为第一个参数调用login(1)
,并从影子文件输入的密码作为第二个参数(如果返回)与第二个参数输入的字符串相同,则用户已成功通过身份验证。
像这样编译并运行:
crypt_r
我之所以说 ,是因为该库支持的一组特殊用途的哈希算法在Unix和Unix之间有所不同。如果(且仅当)您可以将字符串$ gcc -std=gnu11 -O test.c -lcrypt
$ test $(./a.out) = '$6$abcd$vIWAp1OzuGuo376cRkZ5DXcgI8KIlnUibsk.iydtfCFqb9okOz.S70Ysu7.qRRg9Me5XwAyTjkZBQJXiIxwpL/'; echo $?
0
放在$6$abcd$...
的某个帐户的密码条目中,然后使用密码/etc/shadow
作为该帐户成功登录后,它应该可以工作。 / p>
libcrypt可能还具有称为crypt_gensalt_rn
的函数,您可以使用该函数生成设置字符串并选择适当的哈希算法。这是该功能的演示:
appple
如果编译并运行 this 程序,它将不打印以#include <crypt.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
char setting[CRYPT_GENSALT_OUTPUT_SIZE];
crypt_gensalt_rn(0,setting,CRYPT_GENSALT_OUTPUT_SIZE);
struct crypt_data cd;
memset(&cd,&cd));
return 0;
}
开头的字符串;它将打印其他内容,例如
$6$abcd
及其打印的内容将在每次运行时更改,但是它输出的每个字符串都可以用作$y$j9T$0aVoGQ/PFN0PHbcYlKZdZ1$05NbMJLbRliM7fmtSAeZoy3OoRsBqETpAZXQpnPey82
条目,允许某人使用密码/etc/shadow
登录。您可以使用我在0处留下的前四个参数来控制其行为。
(披露:我是lib(x)crypt的作者之一。)
,您可以在GitHub上找到openssl passwd
命令(特别是核心do_passwd
函数)的源代码:https://github.com/openssl/openssl/blob/8ea761bf40e6578ecd95ec47772ef86a2e4d4607/apps/passwd.c#L795-L874
(非常平凡的290行)SHA-512 passwd哈希计算函数位于https://github.com/openssl/openssl/blob/8ea761bf40e6578ecd95ec47772ef86a2e4d4607/apps/passwd.c#L509-L793的稍上方,
最好从应用程序中调用openssl passwd
作为子流程。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。