C 言語で crypt 関数を使用する
この記事では、C 言語で crypt
関数を使用する方法をいくつか説明します。
パスフレーズをハッシュ化して保存するために crypt
関数を使用する
crypt
は、システムへの保存や認証のためのパスフレーズハッシュ法を提供する 4つの関数群です。これらの関数は汎用の暗号ハッシュには適していないことに注意してください。なぜなら、パスフレーズハッシュは高速で処理能力の低い汎用のものに比べて計算量が多くなるからです。
crypt
は二つの char*
引数を const
の修飾パラメータとして渡します。最初の引数はハッシュ化する必要のあるパスフレーズを指し、2 番目の引数は setting
と呼ばれる特殊な文字列で、crypt_gensalt
関数を用いて生成されます。引数 setting
は crypt
関数に複数のパラメータを与えます。ソルトのバイトは暗号的にランダムでなければならず、システム固有の乱数生成ユーティリティとは別に取得できることに注意してください。以下の例は、ランダムバイトの自動取得を示すために、3 番目のパラメータとして crypt_gensalt
に特別な値 - null ポインタを渡した場合を示しています。
ハッシュアルゴリズムには複数のものがあり(詳細はこちらのページを参照してください)、それらは一意の文字列識別子として crypt_gensalt
関数に渡されます。crypt_gensalt
が setting
文字列を返すと、それをパスフレーズと一緒に crypt
関数に渡すことができます。次のサンプルコードでは、"$2b$"
というプレフィックス文字列で識別される bcrypt
アルゴリズムを用いています。関数 crypt_gensalt
の第 2 引数には、ハッシュ生成のコストがどの程度かかるかを指定し、値 0
にはアルゴリズムのデフォルトレベルを指定します。この例では、bcrypt
ハッシュアルゴリズムの推奨値である 15
を指定しています。
#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
バッファに文字が残らずに文字列が読み込まれるようにする必要があります。そのためには、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