在 C 語言中使用 crypt 函式

Jinku Hu 2023年10月12日
  1. 使用 crypt 函式對密碼進行雜湊儲存
  2. 使用嚴格的錯誤處理例程來保證 crypt 函式的成功執行
在 C 語言中使用 crypt 函式

本文將介紹幾種在 C 語言中使用 crypt 函式的方法。

使用 crypt 函式對密碼進行雜湊儲存

crypt 實際上是一個由四個函式組成的系列,提供了用於系統儲存或認證的口令雜湊方法。請注意,這些函式不適合用於通用的加密雜湊,因為與通用函式相比,密碼短語雜湊需要昂貴的計算成本,而通用函式的設計是快速的,使用較少的處理能力。

crypt 接受兩個 char*引數,作為 const 限定引數傳遞。第一個引數指向需要雜湊的口令,第二個引數是稱為 setting 的特殊字串,應該使用 crypt_gensalt 函式生成。setting 引數為 crypt 函式提供了多個引數,如使用哪種雜湊演算法、雜湊的計算成本(越大的值對應成本越高)和隨機鹽位元組。注意,鹽的位元組必須是加密隨機的,它們可以從系統專用的隨機數生成實用程式中單獨獲得。下面的例子演示了特殊值–null 指標作為第三個引數傳遞給 crypt_gensalt 的情況,以表示自動檢索隨機位元組。

有多種雜湊演算法可供選擇(在這個 page 上有詳細介紹),它們作為唯一的字串識別符號傳遞給 crypt_gensalt 函式。一旦 crypt_gensalt 返回 setting 字串,它就可以和密碼一起傳遞給 crypt 函式,返回值將是可列印的 ASCII 文字的雜湊密碼。在接下來的示例程式碼中,我們使用 bcrypt 演算法,識別為"2b$"字首字串。請注意,crypt_gensalt 函式的第二個引數指定了雜湊生成的成本,值 0 指定了給定演算法的預設級別。在本例中,我們指定 15,這是 bcrypt 雜湊演算法的推薦值。

#include "crypt.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

enum { MAX_LEN = 1024 };

int main(int argc, char *argv[]) {
  char *text, *encrypted, *salt;
  size_t len;
  long lnmax;

  text = malloc(MAX_LEN);

  printf("Input string to be hashed: ");
  if (fgets(text, MAX_LEN, stdin) == NULL) exit(EXIT_FAILURE);

  len = strlen(text);
  if (text[len - 1] == '\n') text[len - 1] = '\0';

  salt = crypt_gensalt("$2b$", 15, NULL, 0);
  encrypted = crypt(text, salt);

  printf("Encrypted: %s", encrypted);

  free(text);
  exit(EXIT_SUCCESS);
}

輸出:

Input string to be hashed: hello there
Encrypted: $2b$15$DkpZq2vJRQoBiK4slxfFa.Eml8PUtFB7CYYH1RJH6XML3ujhX8fqy

使用嚴格的錯誤處理例程來保證 crypt 函式的成功執行

前面的示例程式碼從使用者那裡獲取輸入字串,並分配動態記憶體來儲存它,因此,我們需要確保在讀取字串時,stdio 緩衝區中沒有任何剩餘的字元。因此,我們需要確保在讀取字串時,stdio 緩衝區中沒有任何剩餘的字元。為此,我們在 stdout 上呼叫 fflush,然後呼叫 fgets 從使用者那裡獲取輸入字串。另外,注意檢查所有庫函式和系統呼叫的錯誤返回值,並呼叫 perror 輸出相應的資訊。

#include "crypt.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

enum { MAX_LEN = 1024 };

int main(int argc, char *argv[]) {
  char *text, *encrypted, *salt;
  size_t len;
  long lnmax;

  text = malloc(MAX_LEN);
  if (text == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }

  printf("Input string to be hashed: ");
  fflush(stdout);
  if (fgets(text, MAX_LEN, stdin) == NULL) exit(EXIT_FAILURE);

  len = strlen(text);
  if (text[len - 1] == '\n') text[len - 1] = '\0';

  salt = crypt_gensalt("$2b$", 15, NULL, 0);
  if (salt == NULL) {
    perror("crypt_gensalt");
    exit(EXIT_FAILURE);
  }

  encrypted = crypt(text, salt);
  if (encrypted == NULL) {
    perror("crypt_gensalt");
    exit(EXIT_FAILURE);
  }

  printf("Encrypted: %s", encrypted);

  free(text);
  exit(EXIT_SUCCESS);
}

輸出:

Input string to be hashed: hello there
Encrypted: $2b$15$DkpZq2vJRQoBiK4slxfFa.Eml8PUtFB7CYYH1RJH6XML3ujhX8fqy
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook