crypt, crypt_r -
パスワードとデータの暗号化
#define _XOPEN_SOURCE /* feature_test_macros(7) 参照 */
#include <unistd.h>
char *crypt(const char *key, const char *salt);
#define _GNU_SOURCE /* feature_test_macros(7) 参照 */
#include <crypt.h>
char *crypt_r(const char *key, const char *salt,
struct crypt_data *data);
-lcrypt でリンクする。
crypt()
はパスワード暗号化関数である。
鍵探索のハードウェアによる実装を妨げるように(その他にもいろいろ)
変更した Data Encryption Standard
アルゴリズムを元にしている。
key
はユーザーが入力するパスワードである。
salt は集合 [
a-zA-Z0-9./]
から選ばれた 2
文字の文字列である。
この文字列はアルゴリズムの出力を
4096
通りにかき乱すのに使われる。
key の最初の 8
文字の各文字から下位
7 ビットをとって 56
ビットの鍵が得られる。
この 56
ビットの鍵は特定の文字列(ふつうはすべて
0 の文字列)
を繰り返し暗号化するのに用いられる。
返り値は暗号化されたパスワードへのポインターで、13
の印字可能な ASCII 文字
からなる(最初の 2
文字は salt そのもの)。
返り値は、関数呼出しのたびに上書きされる静的なデータへのポインターである。
警告: 鍵空間は 2**56 = 7.2e16
の可能な値から成る。
この鍵空間の全探索は強力な並列計算機を使えば可能である。また
crack(1)
のようなソフトウェアはこの鍵空間の中で、多くの人にパスワードとして
使われるような鍵についての全探索が可能である。
それゆえ、パスワードを選択するときには、すくなくとも、
一般的に使われる単語と名前は避けるべきである。
passwd(1)
を使う時にはクラックされうるパスワードについての検査をすることが
推奨される。
DES
アルゴリズムにはいくつかの癖があり、それによってパスワード認証以外に
crypt()
を使うのはたいへんよくない選択となっている。もし
crypt()
を暗号プロジェクトに使おうという案をもっているならば、それはやめたほうが
よい。暗号化についてのよい本と誰でも入手できる
DES
ライブラリのひとつを
手にいれるべきだ。
crypt_r() は
crypt()
の再入可能版である。
data
で示される構造体は結果データの保存と情報の管理に使われる。
この構造体に対して(メモリーを割り当てること以外に)呼び出し元がするべき唯一の
ことは、
crypt_r()
の初回の呼び出しの前に
data->initialized
をゼロにすることだけである。
成功の場合には、暗号化されたパスワードへのポインターが返される。
エラーの場合には NULL
が返される。
- EINVAL
-
salt
が間違ったフォーマットである。
- ENOSYS
-
crypt()
関数が実装されていない。多分アメリカの輸出規制のために。
- EPERM
-
/proc/sys/crypto/fips_enabled が 0
でない値で、 DES
などの弱い暗号タイプを利用しようとした。
この節で使用されている用語の説明については、
attributes(7) を参照。
インターフェース |
属性 |
値 |
crypt() |
Thread safety |
MT-Unsafe race:crypt |
crypt_r() |
Thread safety |
MT-Safe |
crypt(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.
crypt_r()
は GNU 拡張である。
The
crypt(),
encrypt(3), and
setkey(3) functions are part
of the POSIX.1-2008 XSI Options Group for Encryption and are optional. If the
interfaces are not available, then the symbolic constant
_XOPEN_CRYPT
is either not defined, or it is defined to -1 and availability can be checked
at run time with
sysconf(3). This may be the case if the downstream
distribution has switched from glibc crypt to
libxcrypt. When
recompiling applications in such distributions, the programmer must detect if
_XOPEN_CRYPT is not available and include
<crypt.h> for
the function prototypes; otherwise
libxcrypt is an ABI-compatible
drop-in replacement.
この関数の glibc
版は追加の暗号化アルゴリズムに対応している。
If
salt is a character string starting with the characters
"$
id$" followed by a string optionally terminated by
"$", then the result has the form:
DES を使う代わりに、
id
で使用する暗号化手法を識別し、これがパスワード文字列の残りの部分を解釈する
方法を決定する。
id
の値として、以下の値に対応している:
ID | Method |
|
|
1 | MD5 |
|
2a | Blowfish (本流の glibc
には入っていない; |
|
| いくつかの Linux
ディストリビューションで追加されている) |
|
. |
|
. |
|
. |
|
. |
|
. |
|
. |
|
5 | SHA-256 (glibc 2.7 以降) |
|
6 | SHA-512 (glibc 2.7 以降) |
|
Thus, $5$
salt$
encrypted and $6$
salt$
encrypted
contain the password encrypted with, respectively, functions based on SHA-256
and SHA-512.
"
salt" stands for the up to 16 characters following
"$
id$" in the salt. The "
encrypted" part of
the password string is the actual computed password. The size of this string
is fixed:
MD5 | 22 characters |
|
SHA-256 | 43 characters |
|
SHA-512 | 86 characters |
|
"
salt" と "
encrypted"
の文字は [
a-zA-Z0-9./]
の集合から
選ばれる。 MD5 と SHA
の実装では、
key
全体が意味がある (DES
の場合には最初の 8
文字だけに意味がある)。
Since glibc 2.7, the SHA-256 and SHA-512 implementations support a user-supplied
number of hashing rounds, defaulting to 5000. If the "$
id$"
characters in the salt are followed by "rounds=
xxx$", where
xxx is an integer, then the result has the form
$
id$
rounds=yyy$
salt$
encrypted
where
yyy is the number of hashing rounds actually used. The number of
rounds actually used is 1000 if
xxx is less than 1000, 999999999 if
xxx is greater than 999999999, and is equal to
xxx otherwise.
login(1),
passwd(1),
encrypt(3),
getpass(3),
passwd(5)
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。