C 言語で crypt 関数を使用する

胡金庫 2023年10月12日
  1. パスフレーズをハッシュ化して保存するために crypt 関数を使用する
  2. 厳格なエラー処理ルーチンを用いて crypt 関数の正常な実行を保証する
C 言語で crypt 関数を使用する

この記事では、C 言語で crypt 関数を使用する方法をいくつか説明します。

パスフレーズをハッシュ化して保存するために crypt 関数を使用する

crypt は、システムへの保存や認証のためのパスフレーズハッシュ法を提供する 4つの関数群です。これらの関数は汎用の暗号ハッシュには適していないことに注意してください。なぜなら、パスフレーズハッシュは高速で処理能力の低い汎用のものに比べて計算量が多くなるからです。

crypt は二つの char* 引数を const の修飾パラメータとして渡します。最初の引数はハッシュ化する必要のあるパスフレーズを指し、2 番目の引数は setting と呼ばれる特殊な文字列で、crypt_gensalt 関数を用いて生成されます。引数 settingcrypt 関数に複数のパラメータを与えます。ソルトのバイトは暗号的にランダムでなければならず、システム固有の乱数生成ユーティリティとは別に取得できることに注意してください。以下の例は、ランダムバイトの自動取得を示すために、3 番目のパラメータとして crypt_gensalt に特別な値 - null ポインタを渡した場合を示しています。

ハッシュアルゴリズムには複数のものがあり(詳細はこちらのページを参照してください)、それらは一意の文字列識別子として crypt_gensalt 関数に渡されます。crypt_gensaltsetting 文字列を返すと、それをパスフレーズと一緒に 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 バッファに文字が残らずに文字列が読み込まれるようにする必要があります。そのためには、stdoutfflush を呼び出してから 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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook