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
