在 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