我有一个函数可以测试 sha256 散列中的部分碰撞。在编译成名为sha256
的文件后,终端中的调用如下所示:
./sha256 2612c7
函数sha256
重复生成unsigned char *
变量的随机字节,在这种情况下只需将其称为buffer
,并将第一个k
位与给定的参数进行比较。 buffer
中的哈希值由 OpenSSL 的EVP library生成。
在这种情况下,给出的参数是2612c7
,它存在于argv[1]
中。 k = 24
,因为2612c7
是24位。我需要重复比较buffer
到argv[1]
中的随机散列值,看看它们是否相同,这表示在第一个k
位中发生了冲突。
我对argv[1]
以什么形式存在感到困惑?或者只是如何比较一般?
我写了这个函数:
int match(unsigned char * buffer, unsigned char * hash_value) {
int i = 0;
while(hash_value[i] != '\0') {
if(hash_value[i] != buffer[i]) {
return 0;
}
i++;
}
return 1;
}
我正在使用match
致电match(buffer, (unsigned char *) argv[2])
,但即使极小的k
值(例如./sha256 2
)也未发现任何冲突。
这是完整的代码:
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/random.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* utitlity function to help matching */
int match(unsigned char * md_value, unsigned char * hash_value) {
int i = 0;
while(hash_value[i] != '\0') {
if(hash_value[i] != md_value[i]) {
return 0;
}
i++;
}
return 1;
}
/* ./this.o <digest method> <hash value> */
int main(int argc, char *argv[]) {
/* hash function initiation */
EVP_MD_CTX *mdctx;
const EVP_MD *md;
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len;
/* seeding for random number generator */
void *seed = NULL;
int rseed;
/* random generator initiation */
unsigned char buffer[128];
/* utility variables for counting */
int i = 0;
/* parameter checking */
if (argv[2] == NULL) {
printf("No hash value given\n");
exit(1);
} else if (argv[1] == NULL) {
printf("No digest method given\n");
exit(1);
}
/* get hash method */
OpenSSL_add_all_algorithms();
md = EVP_get_digestbyname(argv[1]);
if (md == NULL) {
printf("Unknown message digest %s\n", argv[1]);
exit(1);
}
/* random generator initialization */
if(RAND_load_file("/dev/random", 32) != 32) {
printf("random initialization failed");
exit(1);
}
do {
/* generate random text */
if(RAND_bytes(buffer, sizeof(buffer)) != 1) {
printf("failed generating random text");
exit(1);
}
/* hash the random text */
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, buffer, strlen(buffer));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
/* reseed random */
rseed = syscall(SYS_getrandom, seed, (size_t) 128, (unsigned int) 1);
RAND_seed(seed, rseed);
i++;
} while(match(md_value, (unsigned char *) argv[2]) == 0);
printf("collision found: %d tries\n", i);
return 0;
}
请注意,使用./a.out sha256 2612c7
调用实际功能,为简单起见,我简化了上面的示例。