CRYPT(3)

NAZWA
crypt, crypt_r, crypt_rn, crypt_ra - miesza (haszuje) hasła

BIBLIOTEKA
libcrypt

SKŁADNIA
<crypt.h> char * crypt(const char *phrase, const char *setting) char * crypt_r(const char *phrase, const char *setting, struct crypt_data *data) char * crypt_rn(const char *phrase, const char *setting, struct crypt_data *data, int size) char * crypt_ra(const char *phrase, const char *setting, void **data, int *size)

OPIS
Funkcje crypt, crypt_r, crypt_rn i crypt_ra nieodwracalnie „mieszają” (haszują) hasła w celu ich przechowywania w systemowej bazie danych haseł (shadow(5)), za pomocą kryptograficznej „metody mieszającej”. Wynik operacji zwany jest „skrótem hasła” lub po prostu „skrótem” („haszem”). Metody mieszania opisano w crypt(5).

setting kontrolują metodę mieszania, która ma zostać zastosowana i przekazują jej różne parametry, w szczególności losową „sól”, która zapewnia, że żadne dwa przechowywane skróty nie są takie same, nawet przy takich samych phrase.

Argument data do crypt_r jest strukturą typu struct crypt_data. Ma co najmniej następujące pola:

    struct crypt_data {
        char output[CRYPT_OUTPUT_SIZE];
        char setting[CRYPT_OUTPUT_SIZE];
        char input[CRYPT_MAX_PASSPHRASE_SIZE];
        char initialized;
    };

Po pomyślnym powrocie z crypt_r, skróty haseł trafią do output. Aplikacje są zachęcane (lecz nie jest to wymagane) do używania pól input i setting, w celu ich przekazania jako input phrase i setting do crypt_r. W ten sposób łatwiejsze będzie usunięcie wszystkich wrażliwych danych, które nie są już potrzebne.

Pole initialized musi wynosić zero przed pierwszym użyciu obiektu struct crypt_data w wywołaniu do crypt_r(). Przed pierwszym użyciem, zaleca się wyzerowanie całego obiektu, a nie tylko initialized i nie jedynie pól udokumentowanych (oczywiście należy to zrobić przed przechowaniem czegokolwiek w setting i input).

Argument data do crypt_rn powinien również wskazywać na obiekt struct crypt_data, przy czym size powinno być rozmiarem tego obiektu, rzutowanym na int. Przy użyciu z crypt_rn, cały obiekt data (poza polami input i setting) musi być wyzerowany przed pierwszym użyciem; nie jest to jedynie zalecenie, jak ma to miejsce w przypadku crypt_r. Poza tym, pola tego obiektu mają te same zastosowania, co dla crypt_r.

Przy pierwszym wywołaniu do crypt_ra, data powinno być adresem zmiennej void * ustawionej na NULL, a size powinno być adresem zmiennej int ustawionej na zero. crypt_ra zaalokuje i zainicjuje obiekt struct crypt_data, za pomocą malloc(3) i zapisze jego adres i rozmiar do zmiennych, na które wskazują data i size. Można ich później użyć ponownie w kolejnych wywołaniach. Po tym, jak aplikacja ukończy mieszanie haseł, powinna zdealokować obiekt struct crypt_data za pomocą free(3).

WARTOŚCI ZWRACANE
Po pomyślnym zakończeniu, crypt, crypt_r, crypt_rn i crypt_ra zwracają wskaźnik do łańcucha kodującego zarówno skrót hasła jak i ustawienia, których użyto, do jego zakodowania. Łańcuch ten może posłużyć jako bezpośrednie setting w innych wywołaniach do crypt, crypt_r, crypt_rn i crypt_ra, oraz jako prefix w wywołaniach do crypt_gensalt, crypt_gensalt_rn i crypt_gensalt_ra. Będzie to łańcuch złożony wyłącznie z drukowalnych znaków ASCII i nie będzie zawierał białych znaków, ani znaków „:”, „;”, „*”, „!” i „\”. Więcej informacji o formacie skrótów haseł znajduje się w podręczniku crypt(5).

crypt places its result in a static storage area, which will be overwritten by subsequent calls to crypt. It is not safe to call crypt from multiple threads simultaneously. It's also not recommended to use the pointer returned as an argument for another call to crypt, as some implementations, including earlier releases of libxcrypt, may overwrite the underlying static output buffer before computing the hash.

crypt_r, crypt_rn, and crypt_ra place their result in the output field of their data argument. It is safe to call them from multiple threads simultaneously, as long as a separate data object is used for each thread. It's also not recommended to use the pointer returned as an argument for another call to crypt_r, crypt_rn, and crypt_ra using the same data object for subsequent calls, as some implementations, including earlier releases of libxcrypt, may overwrite the output field of the passed data argument before computing the hash. Calling crypt_ra with the phrase and/or setting parameters located within a passed data object which is smaller than the size of struct crypt_data is not recommended, as some implementations, including earlier releases of libxcrypt, may not preserve the passed literals, if the data object needs to be altered.

Po wystąpieniu błędu, crypt_r, crypt_rn i crypt_ra zapisują nieprawidłowy skrót w polu output ich argumentu data, a crypt zapisze nieprawidłowy skrót w swojej statycznej przestrzeni przechowywania. Łańcuch ten będzie krótszy niż 13 znaków, będzie rozpoczynał się od znaku „*”, a przy porównaniu nie będzie równy setting.

Po wystąpieniu błędu, crypt_rn i crypt_ra zwrócą pusty wskaźnik. crypt_r i crypt również mogą zwrócić pusty wskaźnik, mogą też zwrócić wskaźnik do nieprawidłowego skrótu, w zależności od konfiguracji libcrypt (opcja zwrócenia nieprawidłowego skrótu istnieje ze względu na kompatybilność ze starszymi aplikacjami, które zakładają, że crypt nie może zwrócić pustego wskaźnika; zob. UWAGI DOTYCZĄCE PRZENOŚNOŚCI niżej).

Wszystkie cztery funkcje ustawiają errno przy niepowodzeniu. Jeśli funkcje się powiodą, wartość errno jest nieokreślona i nie powinna być brana pod uwagę.

BŁĘDY

EINVAL
    setting jest nieprawidłowe lub żądano nieobsługiwanej metody mieszania.

ERANGE
    phrase jest zbyt długie (dłuższe niż CRYPT_MAX_PASSPHRASE_SIZE znaków; niektóre metody mieszania mogą mieć mniejsze limity).
    Tylko crypt_rn: size jest zbyt małe dla metody mieszania zażądanej w setting.

ENOMEM
    Nie udało się zaalokować wewnętrznej pamięci „scratch”.
    Tylko crypt_ra: nie udało się zaalokować pamięci dla data.

ENOSYS lub EOPNOTSUPP
    Mieszanie haseł nie jest obsługiwane w tej instalacji lub metoda mieszania zażądana w setting nie jest obsługiwana. Te statusy błędów nie są używane w tej wersji libcrypt, ale mogą wystąpić na innych systemach.

UWAGI DOTYCZĄCE PRZENOŚNOŚCI
crypt jest wymienione w POSIX, lecz crypt_r, crypt_rn i crypt_ra nie są częścią żadnego standardu.

POSIX nie określa żadnych metod mieszania, ani nie wymaga, aby skróty haseł były przenośne między systemami. W praktyce, skróty haseł są przenośne, o ile oba systemy obsługują daną metodę mieszania. Jednak zestaw obsługiwanych metod mieszania znacznie różni się między systemami.

Zachowanie crypt w przypadku błędów nie jest dobrze zestandaryzowane. Niektóre implementacje nie mogą zawieść (poza załamaniem programu), inne zwracają pusty wskaźnik lub określony łańcuch. Większość implementacji nie ustawia errno, lecz niektóre to robią. POSIX określa zwracanie pustego wskaźnika i ustawianie errno, lecz definiuje tylko jeden możliwy błąd, ENOSYS w przypadku, w którym crypt w ogóle nie jest obsługiwane. Niektóre starsze aplikacje nie są przygotowane do obsługi pustych wskaźników zwracanych przez crypt. Zachowanie opisane powyżej w tej implementacji, czyli ustawianie errno i zwracanie nieprawidłowego skrótu, różnego od setting wybrano, aby takie aplikacje zamknęły się i zawiodły, gdy taki błąd wystąpi.

Z powodów historycznych ograniczeń, dotyczących eksportu oprogramowania kryptograficznego ze Stanów Zjednoczonych, crypt jest opcjonalną częścią POSIX. Aplikacje powinny być dlatego przygotowane do sytuacji, gdy crypt nie jest dostępne, bądź zawsze zawodzić (ustawiając errno na ENOSYS) przy rozruchu.

POSIX określa, że crypt jest zadeklarowane w <unistd.h>, lecz tylko gdy makro _XOPEN_CRYPT jest zdefiniowane i ma wartość większą lub równą zero. Ze względu na to, że libcrypt nie zapewnia <unistd.h>, deklaruje w zamian crypt, crypt_r, crypt_rn i crypt_ra w <crypt.h> .

Na mniejszości systemów (głównie ostatnich wersjach Solarisa), crypt używa statycznego bufora przechowywania przypisanego wątkowi, który czyni bezpiecznym równoczesne wywoływanie z wielu wątków, lecz nie zapobiega każdemu wywołaniu z wątku, przed nadpisaniem wyników poprzedniego wywołania.

USTERKI
Niektóre implementacje crypt, przy błędzie zwracają nieprawidłowy skrót, który jest przechowywany w położeniu tylko do odczytu, lub zainicjowanym jedynie jednokrotnie, co oznacza, że wyczyszczenie bufora, na który wskazuje wartość zwracana przez crypt jest bezpieczne tylko wtedy, gdy nie wystąpił błąd.

struct crypt_data może być dość duże (32kB w tej implementacji libcrypt; ponad 128kB w niektórych innych implementacjach). Jest to na tyle duża wielkość, że może być nierozsądne alokowanie jej na stosie.

Niektóre ostatnio zaprojektowane metody mieszania potrzebują jeszcze więcej pamięci „scratch”, lecz interfejs crypt_r nie umożliwia zmiany rozmiaru struct crypt_data bez złamania kompatybilności binarnej. Interfejs crypt_rn mógłby dokonywać większych alokacji dla określonych metod mieszania, lecz wywołujący crypt_rn nie ma sposobu określenia, jak dużo pamięci zaalokować. crypt_ra sam alokuje pamięć, lecz może wykonać jedynie pojedyncze wywołanie do malloc(3).

ATRYBUTY
Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).
Interfejs | Atrybut | Wartość
 | Bezpieczeństwo wątkowe | MT-niebezpieczne race:crypt
 | Bezpieczeństwo wątkowe | MT-bezpieczne

HISTORIA
Funkcja crypt oparta na wirnikach pojawiła się w AT&T UNIX. „Tradycyjne” crypt, oparte na DES, pojawiło się w AT&T UNIX.

crypt_r pochodzi z biblioteki GNU C. Występuje również funkcja crypt_r na HP-UX i MKS Toolkit, lecz prototypy i zachowanie różnią się.

crypt_rn i crypt_ra pochodzą z projektu Openwall.

ZOBACZ TAKŻE
crypt_gensalt(3), getpass(3), getpwent(3), shadow(3), login(1), passwd(1), crypt(5), passwd(5), shadow(5), pam(8)

TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: Adam Byrtek <alpha@irc.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>, Michał Kułach <michal.kulach@gmail.com> i Robert Luberda <robert@debian.org>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3: https://www.gnu.org/licenses/gpl-3.0.html lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.