CRYPT(3) | Library Functions Manual | CRYPT(3) |
crypt
, crypt_r
,
crypt_rn
, crypt_ra
—
hachage des mot de passe
Crypt Library (libcrypt, -lcrypt)
#include
<crypt.h>
char *
crypt
(const char *motdepasse,
const char *paramètres);
char *
crypt_r
(const char *motdepasse,
const char *paramètres, struct
crypt_data *données);
char *
crypt_rn
(const char *motdepasse,
const char *paramètres, struct
crypt_data *données, int taille);
char *
crypt_ra
(const char *motdepasse,
const char *paramètres, void
**données, int *taille);
Les fonctions crypt
,
crypt_r
, crypt_rn
et
crypt_ra
“hachent” de manière
irréversible motdepasse avant de le stocker
dans la base de données (shadow(5)) des mots de
passe du système en utilisant une “méthode de
hachage” cryptographique. Le résultat de cette
opération se nomme “mot de passe condensé” ou
simplement “condensé.” Les méthodes de hachage
sont décrites dans crypt(5).
paramètres permet de spécifier la méthode de hachage à utiliser, et fournit aussi différents paramètres à cette dernière, en particulier un “salage” (salt) aléatoire qui permet de s'assurer que deux condensés stockés seront toujours différents, même si leurs chaînes motdepasse sont identiques.
L'argument données de
crypt_r
est une structure de type
struct crypt_data. Elle contient au minimum ces
champs :
struct crypt_data { char output[CRYPT_OUTPUT_SIZE]; char setting[CRYPT_OUTPUT_SIZE]; char input[CRYPT_MAX_PASSPHRASE_SIZE]; char initialized; };
Si crypt_r
s'exécute avec
succès, le mot de passe condensé sera stocké dans
output. Même si ce n'est pas obligatoire, il
est recommandé dans les applications d'utiliser les champs
motdepasse et paramètres
pour stocker les chaînes qu'elles passeront à
crypt_r
à l'aide des arguments
motdepasse et paramètres.
Cela facilitera la suppression des données sensibles lorsqu'elles ne
seront plus utilisées.
Le champ initialized doit
être défini à zéro avant la première
utilisation d'un objet de type struct crypt_data dans
un appel à
crypt_r
().
Nous recommandons de définir à zéro l'objet dans son
ensemble avant sa première utilisation, et non pas seulement
initialized et les champs documentés. (Bien
entendu, il faut effectuer cette opération avant de stocker quoi que
ce soit dans paramètres et
entrée.)
L'argument données de
crypt_rn
doit aussi pointer vers un objet de type
struct crypt_data, et taille
doit contenir la taille de ce dernier, convertie en
int. Lorsqu'il est utilisé avec
crypt_rn
, l'objet data dans
son ensemble (à l'exception des champs
entrée et
paramètres) doit être défini
à zéro avant sa première utilisation, et cela n'est pas
une simple recommandation, comme avec crypt_r
. Cela
mis à part, les champs de l'objet s'utilisent de la même
façon qu'avec crypt_r
.
Au premier appel à crypt_ra
,
données doit contenir l'adresse d'une variable
de type void * initialisée à NULL, et
taille l'adresse d'une variable de type
int initialisée à zéro.
crypt_ra
alloue et initialise un objet de type
struct crypt_data en utilisant
malloc(3), et écrit son adresse et sa taille dans
les variables vers lesquelles pointent respectivement
data et taille. Ces
dernières peuvent être réutilisées lors d'appels
ultérieurs à crypt_ra
. Lorsque
l'application a terminé son hachage de mots de passe, elle doit
désallouer l'objet struct crypt_data à
l'aide de free(3).
Si elles s'exécutent avec succès,
crypt
, crypt_r
,
crypt_rn
et crypt_ra
renvoient un pointeur vers une chaîne qui contiendra le mot de passe
condensé et les paramètres qui ont été
utilisés pour le hacher. Cette chaîne est directement
utilisable comme valeur de paramètres lors
d'appels ultérieurs à crypt
,
crypt_r
, crypt_rn
et
crypt_ra
, et comme valeur de
prefix lors d'appels ultérieurs à
crypt_gensalt
,
crypt_gensalt_rn
et
crypt_gensalt_ra
. Elle ne contiendra que des
caractères ASCII imprimables et ne contiendra ni espaces, ni aucun
des caractères ‘:
’,
‘;
’,
‘*
’,
‘!
’ ou
‘\
’. Voir crypt(5)
pour plus de détails sur le format des mots de passe
condensés.
crypt
place son résultat dans une
zone de mémoire statique qui sera écrasée lors d'appels
ultérieurs à crypt
. Il n'est pas sans
danger d'appeler crypt
depuis plusieurs threads
simultanément.
crypt_r
, crypt_rn
et crypt_ra
placent leur résultat dans le
champ output de leur argument
données. On peut sans danger les appeler depuis
plusieurs threads simultanément, sous réserve qu'un objet
données séparé soit
utilisé pour chaque thread.
En cas d'erreur, crypt_r
,
crypt_rn
et crypt_ra
écrivent un mot de passe condensé
non valable dans le
champ output de leur argument
données, et crypt
écrit un condensé non valable dans sa zone de mémoire
statique. La chaîne contiendra moins de 13 caractères,
commencera par un ‘*
’ et sera
différente de paramètres.
En cas d'erreur, crypt_rn
et
crypt_ra
renvoient un pointeur NULL.
crypt_r
et crypt
, quant
à elles, renverront aussi un pointeur NULL ou un pointeur vers le
condensé non valable, selon la manière dont aura
été configurée libcrypt. Cette possibilité de
renvoyer le condensé non valable est offerte à titre de
compatibilité avec les anciennes applications qui partent du principe
que crypt
ne peut pas renvoyer de pointeur NULL
(voir NOTES DE
PORTABILITÉ ci-dessous).
Les quatre fonctions définissent errno en cas d'échec.
EINVAL
ERANGE
CRYPT_MAX_PASSPHRASE_SIZE
; certaines
méthodes de hachage imposeront peut-être des limites plus
basses).
crypt_rn
seulement :
taille est trop petite pour la méthode de
hachage spécifiée par
paramètres.ENOMEM
crypt_ra
seulement : l'allocation de
mémoire pour données a
échoué.ENOSYS
ou
EOPNOTSUPP
crypt
est incluse dans POSIX, mais
crypt_r
, crypt_rn
et
crypt_ra
n'appartiennent à aucune norme.
POSIX ne spécifie aucune méthode de hachage et ne requiert pas la portabilité des mots de passe condensés entre les différents systèmes. En pratique, les mots de passe condensés sont portables entre deux systèmes à partir du moment où ces derniers prennent en charge la méthode de hachage qui a été utilisée. Cependant, le jeu de méthodes de hachage prises en charge varie considérablement d'un système à l'autre.
Le comportement de crypt
en cas d'erreur
n'est pas bien normalisé. Certaines implémentations n'ont tout
simplement pas prévu d'échouer (hormis en plantant le
programme), alors que d'autres renvoient un pointeur NULL ou une
chaîne prédéfinie. Certaines implémentations
définissent errno, mais la plupart ne le font
pas. POSIX préconise de renvoyer un pointeur NULL et de
définir errno, mais il ne définit qu'une
erreur possible, ENOSYS
, dans le cas où
crypt
n'est pas du tout pris en charge. Certaines
applications plus anciennes n'ont pas été conçues pour
gérer les pointeurs NULL renvoyés par
crypt
. On choisit alors le comportement
décrit plus haut pour cette implémentation, à savoir
définir errno et renvoyer un mot de passe
condensé non valable et différent de
paramètres, de façon à ce que ces
applications échouent en se terminant lorsqu'une erreur survient.
Suite aux restrictions historiques à l'exportation des
logiciels cryptographiques depuis les USA, crypt
est
un composant POSIX optionnel. Les applications doivent donc prévoir
l'éventualité que crypt
ne soit pas
disponible ou échoue systématiquement à
l'exécution (en définissant errno
à ENOSYS
).
POSIX spécifie que crypt
est
déclaré dans
<unistd.h,>
mais seulement
si la macro _XOPEN_CRYPT
est définie et si sa
valeur est supérieure ou égale à zéro. Comme
libcrypt ne fournit pas
<unistd.h,>
elle
déclare crypt
,
crypt_r
, crypt_rn
et
crypt_ra
dans
<crypt.h>
à la
place.
Sur une minorité de systèmes (en particulier les
versions récentes de Solaris), crypt
utilise
un tampon mémoire statique spécifique aux threads qui lui
permet d'être appelée sans danger depuis plusieurs threads
simultanément, mais n'empêche pas chaque appel depuis un
thread d'écraser les résultats de l'appel
précédent.
En cas d'erreur, certaines implémentations de
crypt
renvoient un condensé non valable qui
est stocké dans une zone en lecture seule ou seulement
initialisé une fois, ce qui signifie que l'on ne peut supprimer sans
danger le tampon pointé par la valeur de retour de
crypt
que si aucune erreur n'est survenue.
struct crypt_data peut avoir une taille assez importante (32ko dans cette implémentation de libcrypt ; plus de 128ko dans certaines autres implémentations). Cette taille est suffisamment importante pour qu'il soit malavisé de l'allouer dans la pile.
Certaines méthodes de hachage récentes
nécessitent encore plus de mémoire de travail, mais
l'interface crypt_r
rend impossible de modifier la
taille de struct crypt_data sans casser la
compatibilité binaire. L'interface crypt_rn
pourrait accorder plus de mémoire pour certaines méthodes de
hachage spécifiques, mais l'appelant de
crypt_rn
n'a aucun moyen de connaître la
quantité de mémoire à allouer.
crypt_ra
effectue l'allocation de mémoire
elle-même, mais ne peut effectuer qu'un seul appel à
malloc(3).
Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface | Attribut | Valeur |
crypt | Sécurité des threads | MT-Unsafe race:crypt |
crypt_r , crypt_rn , crypt_ra | Sécurité des threads | MT-Safe |
Une fonction crypt
s'inspirant des
machines à rotor est apparue dans Version 6
AT&T UNIX. La fonction crypt
“traditionnelle” basée sur DES est quant à elle
apparue dans Version 7 AT&T UNIX.
crypt_r
trouve ses origines dans la
bibliothèque GNU C. Il existe aussi une fonction
crypt_r
sur HP-UX et dans la boîte à
outils MKS, mais leurs prototype et sémantique diffèrent.
crypt_rn
et
crypt_ra
trouvent leur origine dans le projet
Openwall.
crypt_gensalt(3), getpass(3), getpwent(3), shadow(3), login(1), passwd(1), crypt(5), passwd(5), shadow(5), pam(8)
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Lucien Gentis <lucien.gentis@waika9.com>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org
11 Octobre 2017 | Projet Openwall |