使用多线程时,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.

因此你的问题。