在 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 "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "crypt.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 "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "crypt.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
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn