这是我第一次用C编写代码。我的sha512有问题。结果与其他语言(php,python)不同。
我的目标是使用sha512更多次加密字符串循环。但第一次和第二次与python或php相同,但从第三次开始,它是不同的。
结果图片:
在Linux上运行。
这是我的代码:
C
$ gcc test.c -lcrypto -o test
$ ./test
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
char *hash_sha512(char *data) {
SHA512_CTX ctx;
char *md = malloc(sizeof(char)*(SHA512_DIGEST_LENGTH+1));
SHA512_Init(&ctx);
SHA512_Update(&ctx, data, strlen(data));
SHA512_Final(md, &ctx);
md[SHA512_DIGEST_LENGTH] = '\0';
return md;
}
int main(void) {
char *str = hash_sha512("123456");
FILE *fp;
int count = 10;
fp = fopen("/tmp/c.txt", "w+");
do {
fputs(str, fp);
fputs("\n", fp);
str = hash_sha512(str);
} while (--count);
fclose(fp);
return 0;
}
PHP
<?php
$password='123456';
$hash = hash('sha512', $password, TRUE);
$i = 10;
do {
file_put_contents('/tmp/php.txt',$hash . "\n", FILE_APPEND);
$hash = hash('sha512', $hash, TRUE);
} while (--$i);
的Python
#! /usr/bin/env python
import hashlib
password='123456'
count = 10
f = open('/tmp/python.txt','a')
pass_hash = hashlib.sha512(password).digest()
for _ in range(count):
f.write(pass_hash)
pass_hash = hashlib.sha512(pass_hash).digest()
f.close()
答案 0 :(得分:1)
您不是在比较苹果和苹果,并且在此过程中也没有正确计算您的C代码的摘要。从sha512摘要发出的字节流不是C字符串,并且在末尾放置零字符不会神奇地使它成为一个字符串。例如,第一个摘要看起来像这样(十六进制):
ba 32 53 87 6a ed 6b c2 2d 4a 6f f5 3d 84 06 c6
ad 86 41 95 ed 14 4a b5 c8 76 21 b6 c2 33 b5 48
ba ea e6 95 6d f3 46 ec 8c 17 f5 ea 10 f3 5e e3
cb c5 14 79 7e d7 dd d3 14 54 64 e2 a0 ba b4 13
第二个摘要是:
73 14 8c 26 3f fc 49 86 34 cc 1e be bd 67 51 69
97 01 11 69 a3 7e 28 11 ed 51 d5 2c 82 d4 d5 72
af 32 c2 31 13 9f 1d 0f d7 af e2 9e 44 1d 44 ae
fa 29 c1 85 5e c6 52 07 63 92 72 11 0d 19 56 74
和第三个,这个:
a5 b2 65 20 84 63 58 8b 56 c1 08 4c 37 03 c4 a1
a9 0c 71 05 89 cb 09 fc 22 07 85 8f 64 3b b1 72
8b 3e f3 f3 06 2c 84 72 f8 3a c6 1f f9 47 87 b8
b8 00 3d 73 0b 29 a3 7b 88 a9 e3 14 ee 19 06 f7
你看到了吗?看看最后一组八位字节。最后一行,第二个字节。
b8 00 3d 73 0b 29 a3 7b 88 a9 e3 14 ee 19 06 f7
^^
由于您的摘要源长度错误地基于C字符串长度,因此它被截断。其余字节将被忽略,您的摘要链将永远错误。
除此之外,您的代码泄漏了内存,就像筛子泄漏雨水一样。对于640字节和10次迭代来说可能不是什么大问题,但是将其移动到一百万次迭代并开始累加。把它放在一个关键任务软件中,这是完全不可接受的。考虑一下:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
void hash_sha512(unsigned char const *src, size_t len, unsigned char *dst)
{
SHA512_CTX ctx;
SHA512_Init(&ctx);
SHA512_Update(&ctx, src, len);
SHA512_Final(dst, &ctx);
}
int main(void)
{
char pwd[] = "123456"
unsigned char digest[2][SHA512_DIGEST_LENGTH] = {{0}};
hash_sha512((unsigned char*)pwd, strlen(pwd), digest[0]);
unsigned int count=1;
for (; count<10; ++count)
{
hash_sha512(digest[(count-1)%2], SHA512_DIGEST_LENGTH, digest[count%2]);
}
return 0;
}
这解决了前面描述的问题,最终的摘要将在digest[(count-1)%2]
。我留给您整合文件IO。下面是使用初始密码"123456"
的前10次迭代供您参考。我建议您使用hexdump
来确保按计划进行。
十次迭代
ba 32 53 87 6a ed 6b c2 2d 4a 6f f5 3d 84 06 c6
ad 86 41 95 ed 14 4a b5 c8 76 21 b6 c2 33 b5 48
ba ea e6 95 6d f3 46 ec 8c 17 f5 ea 10 f3 5e e3
cb c5 14 79 7e d7 dd d3 14 54 64 e2 a0 ba b4 13
73 14 8c 26 3f fc 49 86 34 cc 1e be bd 67 51 69
97 01 11 69 a3 7e 28 11 ed 51 d5 2c 82 d4 d5 72
af 32 c2 31 13 9f 1d 0f d7 af e2 9e 44 1d 44 ae
fa 29 c1 85 5e c6 52 07 63 92 72 11 0d 19 56 74
a5 b2 65 20 84 63 58 8b 56 c1 08 4c 37 03 c4 a1
a9 0c 71 05 89 cb 09 fc 22 07 85 8f 64 3b b1 72
8b 3e f3 f3 06 2c 84 72 f8 3a c6 1f f9 47 87 b8
b8 00 3d 73 0b 29 a3 7b 88 a9 e3 14 ee 19 06 f7
75 15 b6 cb ef 3e 0b 4a 35 e3 58 b9 8b bb a3 2d
a0 bd 1e c8 9d 32 23 7c 09 ae c0 a7 f7 4e 70 35
c8 34 dd 2a ac 8d e4 e9 d1 e8 b5 7a 80 d8 80 db
07 7c 28 18 e8 30 40 aa 06 85 a5 2a 63 41 c6 b7
4d 25 d3 24 5e 22 b1 e4 e4 3f 1e a4 4e a3 eb e4
89 ab e3 c2 63 56 01 17 ea 1f 85 58 d4 da d2 63
6d 9c 2f 74 39 b6 87 85 2c 1c 27 f8 a8 9d 2a cf
ee 64 1c d9 28 5d 88 e5 c7 8b 9f 6e 1e c8 dd 99
17 e2 7f 2f fd a7 c3 b7 41 73 b9 2d e7 61 6e 77
72 79 41 16 14 90 01 db 6f 66 3b e6 12 94 22 06
a9 91 14 55 ab 7f 3a 34 eb 12 b3 a9 78 69 6a 23
8e 82 13 46 1e ed b4 33 e8 74 f8 15 15 a3 19 57
c1 60 9e c9 c4 82 4f 1c 71 a7 e2 7c 6e fc d9 5b
63 4f 27 25 ec fe d2 58 d6 77 61 8f 93 a1 a4 1e
f0 b7 8a 24 36 91 40 9b 5f dd c3 b5 b9 e1 c6 97
24 66 89 b0 79 c2 84 05 8e 4f 43 4b 5a bb 53 e6
7b f9 4c 45 be 2f 29 68 80 36 79 b7 1a 79 36 a3
7e 8b 9f 6e a0 80 3a 9e 5c bc 27 39 bd 2e 6e 9f
5a b2 8c b9 7f 43 9f b2 c4 72 41 99 f7 65 71 26
b7 b8 06 24 a8 34 ea 69 e4 05 ab 55 a7 a8 32 c2
1a 28 09 ee c5 a4 e5 86 98 0f 52 a1 fd ff a6 14
0f 3f 8b 14 85 34 bd a6 bd 45 54 2e 4c 2b da 62
d0 7c 98 38 5c 98 cd 76 df 18 ca 36 16 f2 be 8e
6c ed 76 e8 28 39 e6 38 d7 41 a4 9e 31 6d f0 ab
ce 0c 0f 2e 89 e5 1d c3 58 88 a3 1f a6 7c 18 74
1a 20 d3 84 43 9c 3a e8 4b d9 f1 fe 2e a1 67 0b
62 62 2d dc 02 eb 82 cd 90 b2 0f 8f e2 fe f5 43
7a ad 0c b1 62 d7 e9 45 3f be 14 53 2e b6 d0 68
答案 1 :(得分:1)
感谢@WhozCraig。
这是我的最终代码。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
int main(void) {
char pwd[] = "123456";
unsigned char digest[2][SHA512_DIGEST_LENGTH] = {{0}};
SHA512((unsigned char*)pwd, strlen(pwd), digest[0]);
unsigned int count = 1;
for (; count<10; ++count) {
SHA512(digest[(count-1)%2], SHA512_DIGEST_LENGTH, digest[count%2]);
}
unsigned char result[SHA512_DIGEST_LENGTH * 2 + 1];
unsigned int i = 0;
for(; i < SHA512_DIGEST_LENGTH; i++) {
sprintf(&result[i*2], "%02x", digest[(count-1)%2][i]);
}
printf("The result is %s.\n", result);
return 0;
}