使用多线程时,crypt 返回具有相同输入和 salt 的不同哈希值
crypt returning different hashes with same input and salt when using multi threading
我正在尝试实施一种简单的暴力破解技术,该技术可以解密包含两个字母和两个数字的加密密码,例如。 AA15。这是我的大学项目,它需要使用多线程。所以我创建了两个内核函数,然后分配给两个线程。一个线程将从字母 A 解密到 M,另一个线程从 N 解密到 Z。在我添加多线程之前,这段代码工作正常。现在 crypt 方法 returns 相同盐和输入的不同哈希值。如果我只使用一个线程,它工作正常。
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <crypt.h>
#include <time.h>
#include <pthread.h>
char pp[] = "$AS$KDz2YK3J483TubP5vGxy79Xa1cmV8e75Asy0ekjoV7HtuS7EAjnH.xWmVng0IhoIg12JEzlnHFcu9UzS1tbXk1";
char *encrypted_password = pp;
void substr(char *dest, char *src, int start, int length)
{
memcpy(dest, src + start, length);
*(dest + length) = '[=10=]';
}
void *function()
{
pthread_t t1, t2;
void *kernel_function_1();
void *kernel_function_2();
pthread_create(&t1, NULL, kernel_function_1, (void *)(encrypted_password));
pthread_create(&t2, NULL, kernel_function_2, (void *)(encrypted_password));
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
void *kernel_function_1(char *salt_and_encrypted)
{
int h, i, j; // Loop counters
char salt[7]; // String used in hashing the password. Need space for [=10=]
char plain[7]; // The combination of letters currently being checked
char *enc; // Pointer to the encrypted password
int count = 0; // The number of combinations explored so far
substr(salt, salt_and_encrypted, 0, 6);
for (h = 'A'; h <= 'M'; h++)
{
for (i = 'A'; i <= 'Z'; i++)
{
for (j = 0; j <= 99; j++)
{
sprintf(plain, "%c%c%02d", h, i, j);
enc = (char *)crypt(plain, salt);
count++;
if (strcmp(salt_and_encrypted, enc) == 0)
{
printf("#%-8d%s %s\n", count, plain, enc);
exit(0);
}
else
{
printf(" %-8d%s %s\n", count, plain, enc);
}
}
}
}
printf("%d solutions explored\n", count);
}
void *kernel_function_2(char *salt_and_encrypted)
{
int x, y, z; // Loop counters
char salt[7]; // String used in hashing the password. Need space for [=10=]
char plain[7]; // The combination of letters currently being checked
char *enc; // Pointer to the encrypted password
int count = 0; // The number of combinations explored so far
substr(salt, salt_and_encrypted, 0, 6);
for (x = 'N'; x <= 'Z'; x++)
{
for (y = 'A'; y <= 'Z'; y++)
{
for (z = 0; z <= 99; z++)
{
sprintf(plain, "%c%c%02d", x, y, z);
enc = (char *)crypt(plain, salt);
count++;
if (strcmp(salt_and_encrypted, enc) == 0)
{
printf("#%-8d%s %s\n", count, plain, enc);
exit(0);
}
else
{
printf(" %-8d%s %s\n", count, plain, enc);
}
}
}
}
printf("%d solutions explored\n", count);
}
int time_difference(struct timespec *start, struct timespec *finish,
long long int *difference)
{
long long int ds = finish->tv_sec - start->tv_sec;
long long int dn = finish->tv_nsec - start->tv_nsec;
if (dn < 0)
{
ds--;
dn += 1000000000;
}
*difference = ds * 1000000000 + dn;
return !(*difference > 0);
}
int main(int argc, char *argv[])
{
struct timespec start, finish;
long long int time_elapsed;
clock_gettime(CLOCK_MONOTONIC, &start);
function();
clock_gettime(CLOCK_MONOTONIC, &finish);
time_difference(&start, &finish, &time_elapsed);
printf("Time elapsed was %lldns or %0.9lfs\n", time_elapsed,
(time_elapsed / 1.0e9));
return 0;
}
Outputs in terminal
我输入
crypt h c
变成 google。最热门的话题之一是 crypt 函数的文档。
我读了docs。
The return value of crypt() points to static data that is overwritten by each call.
所以两个线程共享一个内部缓冲区。
The crypt() function need not be reentrant. A function that is not required to be reentrant is not required to be thread-safe.
因此你的问题。
我正在尝试实施一种简单的暴力破解技术,该技术可以解密包含两个字母和两个数字的加密密码,例如。 AA15。这是我的大学项目,它需要使用多线程。所以我创建了两个内核函数,然后分配给两个线程。一个线程将从字母 A 解密到 M,另一个线程从 N 解密到 Z。在我添加多线程之前,这段代码工作正常。现在 crypt 方法 returns 相同盐和输入的不同哈希值。如果我只使用一个线程,它工作正常。
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <crypt.h>
#include <time.h>
#include <pthread.h>
char pp[] = "$AS$KDz2YK3J483TubP5vGxy79Xa1cmV8e75Asy0ekjoV7HtuS7EAjnH.xWmVng0IhoIg12JEzlnHFcu9UzS1tbXk1";
char *encrypted_password = pp;
void substr(char *dest, char *src, int start, int length)
{
memcpy(dest, src + start, length);
*(dest + length) = '[=10=]';
}
void *function()
{
pthread_t t1, t2;
void *kernel_function_1();
void *kernel_function_2();
pthread_create(&t1, NULL, kernel_function_1, (void *)(encrypted_password));
pthread_create(&t2, NULL, kernel_function_2, (void *)(encrypted_password));
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
void *kernel_function_1(char *salt_and_encrypted)
{
int h, i, j; // Loop counters
char salt[7]; // String used in hashing the password. Need space for [=10=]
char plain[7]; // The combination of letters currently being checked
char *enc; // Pointer to the encrypted password
int count = 0; // The number of combinations explored so far
substr(salt, salt_and_encrypted, 0, 6);
for (h = 'A'; h <= 'M'; h++)
{
for (i = 'A'; i <= 'Z'; i++)
{
for (j = 0; j <= 99; j++)
{
sprintf(plain, "%c%c%02d", h, i, j);
enc = (char *)crypt(plain, salt);
count++;
if (strcmp(salt_and_encrypted, enc) == 0)
{
printf("#%-8d%s %s\n", count, plain, enc);
exit(0);
}
else
{
printf(" %-8d%s %s\n", count, plain, enc);
}
}
}
}
printf("%d solutions explored\n", count);
}
void *kernel_function_2(char *salt_and_encrypted)
{
int x, y, z; // Loop counters
char salt[7]; // String used in hashing the password. Need space for [=10=]
char plain[7]; // The combination of letters currently being checked
char *enc; // Pointer to the encrypted password
int count = 0; // The number of combinations explored so far
substr(salt, salt_and_encrypted, 0, 6);
for (x = 'N'; x <= 'Z'; x++)
{
for (y = 'A'; y <= 'Z'; y++)
{
for (z = 0; z <= 99; z++)
{
sprintf(plain, "%c%c%02d", x, y, z);
enc = (char *)crypt(plain, salt);
count++;
if (strcmp(salt_and_encrypted, enc) == 0)
{
printf("#%-8d%s %s\n", count, plain, enc);
exit(0);
}
else
{
printf(" %-8d%s %s\n", count, plain, enc);
}
}
}
}
printf("%d solutions explored\n", count);
}
int time_difference(struct timespec *start, struct timespec *finish,
long long int *difference)
{
long long int ds = finish->tv_sec - start->tv_sec;
long long int dn = finish->tv_nsec - start->tv_nsec;
if (dn < 0)
{
ds--;
dn += 1000000000;
}
*difference = ds * 1000000000 + dn;
return !(*difference > 0);
}
int main(int argc, char *argv[])
{
struct timespec start, finish;
long long int time_elapsed;
clock_gettime(CLOCK_MONOTONIC, &start);
function();
clock_gettime(CLOCK_MONOTONIC, &finish);
time_difference(&start, &finish, &time_elapsed);
printf("Time elapsed was %lldns or %0.9lfs\n", time_elapsed,
(time_elapsed / 1.0e9));
return 0;
}
Outputs in terminal
我输入
crypt h c
变成 google。最热门的话题之一是 crypt 函数的文档。
我读了docs。
The return value of crypt() points to static data that is overwritten by each call.
所以两个线程共享一个内部缓冲区。
The crypt() function need not be reentrant. A function that is not required to be reentrant is not required to be thread-safe.
因此你的问题。