这是我程序的输出:
Username: paolo
Password: paolo
254835d73cc88095a30fc74133beabe9d8463b2954493227b205ea326c8a9c86
254835d73cc88095a30fc74133beabe9d8463b2954493227b205ea326c8a9c86
No user or password inside the database;
这是我的计划:
int main(void){
int isok = -1;
char *user = NULL, *pass = NULL;
printf("Username: ");
if(scanf("%m[^\n]%*c", &user) == EOF){
perror("scanf user");
return EXIT_FAILURE;
}
printf("Password: ");
if(scanf("%m[^\n]%*c", &pass) == EOF){
perror("scanf");
free(user);
return EXIT_FAILURE;
}
isok = check_login(user, pass);
if(isok == 0){
/* some code here */
}
else{
/* some code here */
}
return EXIT_SUCCESS;
}
int check_login(char *u, char *p){
int retval = -1;
FILE *fp = NULL;
char *tmp, *tmp2, *line = NULL;
/* some code here */
while(fgets(line, 255, fp) != NULL){
tmp = strtok(line, " ");
if(tmp == NULL){
perror("strtok 1");
free(u);
free(p);
free(line);
free(fp);
return -1;
}
tmp2 = strtok(NULL, "\n");
if(tmp2 == NULL){
perror("strtok 2");
free(u);
free(p);
free(line);
free(fp);
return -1;
}
retval = hash_pwd(p, (unsigned char *)tmp2);
if((strcmp(tmp,u) == 0) && (retval == 0)){
free(line);
free(fp);
return 0;
}
else{
continue;
}
}
return -1;
}
int hash_pwd(char *to_hash, unsigned char *tocheck){
SHA256_CTX context;
unsigned char md[SHA256_DIGEST_LENGTH];
size_t length = strlen((const char*)to_hash);
int i;
SHA256_Init(&context);
SHA256_Update(&context, (unsigned char*)to_hash, length);
SHA256_Final(md, &context);
for(i=0; i<SHA256_DIGEST_LENGTH; i++){
printf("%02x", md[i]);
}
printf("\n%s\n", tocheck);
for(i=0; i<SHA256_DIGEST_LENGTH; i++){
if(md[i] == tocheck[i]) continue;
else return 1;
}
return 0;
}
为什么我在函数 hash-pwd 中的比较不起作用?
我做错了什么?
答案 0 :(得分:4)
它不起作用的原因是一个是指向包含十六进制值的ascii字符串的指针;另一个是二进制值数组(您打印为十六进制)。
....
// print out the digest - a binary array of SHA256_DIGEST_LENGTH
// bytes printed in hex
for(i=0; i<SHA256_DIGEST_LENGTH; i++){
printf("%02x", md[i]);
}
// A string of SHA256_DIGEST_LENGTH *2 + 1 length - containing
// the value in hex spelled out in ascii.
printf("\n%s\n", tocheck);
所以你需要转换到另一个。然后比较。
答案 1 :(得分:1)
你怎么知道哈希比较失败了?它也可以是strcmp()
电话:
if((strcmp(tmp,u) == 0) && (retval == 0)){
例如,您确定tmp
不包含u
中缺少的换行符吗?
此外,不确定您是否正确处理哈希加载,如果文件中有一长串十六进制字符,则需要将其转换为二进制 相比较。 SHA256计算的哈希是二进制,而不是十六进制字符串。
有两种(在我看来)合理的解决方法:
你可以看到这两种解决方案是彼此的补充,这对我来说似乎很自然。我不鼓励您在评论中提到的解决方案,涉及临时文件。
在上面,第二个可能是最容易实现的,因为将一堆字节转换为十六进制比执行反向更容易。这是我会使用的解决方案,例如:
static int hash_to_string(char *output, size_t output_max,
const unsigned char *hash, size_t hash_size)
{
size_t i;
if(output_max < 2 * hash_size + 1)
return 0;
for(i = 0; i < hash_size; ++i)
sprintf(output + 2 * i, "%02x", hash[i] & 0xff);
output[2 * i] = '\0';
return 1;
}
使用指向足够容纳字符串版本的缓冲区的指针调用上面的内容,然后将其与从文件加载的缓冲区进行比较。
更新:或者,您可以使用现有的API,只需调用SHA256_End()
即可获得十六进制的哈希值。
作为一般观察,不要这样做:
for(i=0; i<SHA256_DIGEST_LENGTH; i++){
if(md[i] == tocheck[i]) continue;
else return 1;
}
return 0;
相反,请执行此操作:
return memcmp(md, tocheck, sizeof md) != 0;