/* gulliver-10ans-random-pass-gen: generation of user password with /dev/urandom using characters in string "GULLIVER 10 DIX ANS, LOGICIELS LIBRES OEUVRES LIBRES" Version: 1.2 - 2008-10-12 Original author: Thomas PORNIN (see below) Modifications by David MENTRE This program is in the Public Domain. Original author as provided his code as-is and don't want to hear of it (source: private communication). For any comment on this program, send them to David MENTRE. Reviews are welcome. Compile with: gcc -Wall -o gulliver-10ans-random-pass-gen \ gulliver-10ans-random-pass-gen.c Should work on any Un*x-like system. Run the program only once! Don't repeat it until you find an easy password as you would loose the randomness of this approach. */ #include #include #include #include #include /* return a random integer x in 0 <= x < max */ static unsigned randval(int rand_fd, unsigned max) { unsigned val; do { unsigned char x; for (;;) { if (read(rand_fd, &x, 1) <= 0) { if (errno == EINTR) continue; perror("read"); exit(EXIT_FAILURE); } break; } /* after this point: x has a random value such that 0 <= x < 256 */ val = x; } while (val >= max * (256 / max)); /* after this point: 0 <= val < max * |_ 256 / max _|. In other words, there is an integer k so that 0 <= val < max * k. So each integer n in 0 <= n < max has as much probability to be chosen by val. */ return val % max; } static int rand_gulliver(int rand_fd) { return "01ABCDEGILNORSUVX"[randval(rand_fd, 17)]; } int main(void) { static int rand_fd = -1; rand_fd = open("/dev/urandom", O_RDONLY); if (rand_fd < 0) { perror("open"); exit(EXIT_FAILURE); } printf("%c%c%c%c%c%c%c%c%c%c\n", rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd), rand_gulliver(rand_fd)); /* Generated password has: log_2(17^10) > 40 bits of entropy */ close(rand_fd); return EXIT_SUCCESS; } /* The above program is a modification of following Usenet post. From: pornin@nerim.net (Thomas Pornin) Newsgroups: fr.misc.cryptologie Subject: Re: Quel logiciel libre de génération de mots de passe ? Date: Sun, 23 Jul 2006 11:39:33 +0000 (UTC) Message-ID: References: <87odw08nep.fsf@gmail.com> According to David MENTRE : > Je cherche un logiciel libre de génération aléatoire de mots de passe de > « bonne qualité ». Yakademander : =================================================================== #include #include #include #include #include #include #include static unsigned randval(unsigned max) { static int r = -1; unsigned char x; if (r < 0) { r = open("/dev/urandom", O_RDONLY); if (r < 0) { perror("open"); exit(EXIT_FAILURE); } } for (;;) { unsigned val; for (;;) { if (read(r, &x, 1) <= 0) { if (errno == EINTR) continue; perror("read"); exit(EXIT_FAILURE); } break; } val = (unsigned)x; if (val >= max * (256 / max)) continue; return val % max; } } static int randletter(void) { return "abcdefghijklmnopqrstuvwxyz"[randval(26)]; } static int randdigit(void) { return "0123456789"[randval(10)]; } int main(void) { printf("%c%c%c%c%c%c%c%c\n", randletter(), randletter(), randdigit(), randdigit(), randletter(), randletter(), randdigit(), randdigit()); return EXIT_SUCCESS; } =================================================================== Ça tourne sous Linux ou FreeBSD, ou n'importe quel autre unixoïde qui a un /dev/random. À chaque appel, ça génére un nouveau mot de passe de huit caractères : deux lettres minuscules, deux chiffres, deux lettres minuscules, deux chiffres. À l'usage, c'est assez facile à retenir. Entropie légèrement supérieure à 32 bits ; c'est suffisant pour la plupart des usages de mots de passe (c'est une question de protocole). Évidemment, l'entropie n'est atteinte que si on accepte le résultat. Si on fait tourner le programme plusieurs fois, jusqu'à obtenir un mot de passe "facilement mémorisable", alors on bousille l'entropie. --Thomas Pornin */