J'ai écrit ce script mais [:alnum:]
ne fonctionne pas. Quelqu'un aide?
echo -n "Enter a password : "
read password
LEN=$(echo ${#password})
if [ $LEN -lt 10 ]; then
echo "$password is smaller than 10 characters"
else
if ! [ -z `echo $password | tr -d "[:alnum:]"` ]; then
echo "$password is a weak password"
else
echo "$password is a strong password"
fi
fi
echo
Si vous voulez vraiment vérifier la force des mots de passe, vous devriez utiliser cracklib-check
du paquetage cracklib-runtime
(devrait être installé par défaut):
$ echo foo | cracklib-check
foo: it is WAY too short
$ echo foobar | cracklib-check
foobar: it is based on a dictionary Word
$ echo foobared | cracklib-check
foobared: it is based on a dictionary Word
$ echo foobared123 | cracklib-check
foobared123: it is too simplistic/systematic
$ echo '!'foobared123 | cracklib-check
!foobared123: OK
Il y a plusieurs problèmes avec votre script. Il se brise si le mot de passe contient un certain nombre de caractères spéciaux. Essayez d'entrer des entrées telles que:
a space
two spaces
a * star ← try this one in different directories
bbbbbbbbbb ← try this one in a directory containing a file called a
endswithabackslash\
Lire Pourquoi mon script Shell s'étouffe-t-il avec des espaces ou d'autres caractères spéciaux?. Tout. N'écrivez aucun script Shell lié à la sécurité à distance tant que vous ne comprenez pas tout.
Oh, et [:alnum:]
fonctionne parfaitement. Vous avez probablement eu l'intention d'écrire if [ -z …
ou if ! [ -n …
au lieu de if ! [ -z …
.
L'idée de "force du mot de passe" est un mythe. C'est un mythe qui est répandu par beaucoup de sites Web, mais c'est toujours un mythe. La force d'un mot de passe n'existe pas il n'y a que la force d'un processus de génération de mot de passe .
Avoir des caractères spéciaux dans un mot de passe ne le rend pas plus fort. Un mot de passe est un compromis entre facilité de mémorisation et facilité de craquage, et les caractères spéciaux rendent les mots de passe beaucoup plus difficiles à mémoriser mais pas beaucoup plus difficiles à déchiffrer , comme analysé dans ce fil sur Security Stack Exchange ( la nouvelle , le calcul , quelques compléments - exercice: dans cette réponse fausse , lequel les parties ignorent complètement les faits?). L'idée que les caractères spéciaux renforcent un mot de passe repose sur l'hypothèse que les auteurs de piratages de mots de passe sont des idiots. Devinez quoi: ils ne sont pas. En déchiffrant des mots de passe, il y a de l'argent à gagner. Vous pouvez donc parier que des gens investissent pour le faire correctement.
Au hasard. Si votre méthode pour choisir un mot de passe n'inclut pas de source aléatoire (avec un ordinateur, ou si vous aimez lancer les dés si vous l'aimez à l'ancienne), c'est inutile.
Diceware est un choix courant, mais toute méthode qui suit le motif XKCD - choisissez plusieurs "mots" au hasard dans un dictionnaire - est bonne.
#!/bin/sh
echo -n "Enter a password : "
IFS= read -r password
LEN=${#password}
if [ "$LEN" -lt 10 ]; then
printf "%s is smaller than 10 characters\n" "$password"
fi
if [ -z "$(printf %s "$password" | tr -d "[:alnum:]")" ]; then
printf "%s only contains ASCII letters and digits\n" "$password"
else
printf "%s contains characters other than ASCII letters and digits\n" "$password"
fi
Utiliser tr
de cette manière complique les choses. Le shell est parfaitement capable de vérifier si une chaîne contient des caractères appartenant à un certain ensemble.
#!/bin/sh
echo -n "Enter a password : "
IFS= read -r password
LEN=${#password}
if [ "$LEN" -lt 10 ]; then
printf "%s is smaller than 10 characters\n" "$password"
fi
case "$password" in
*[![:alnum:]]*)
printf "%s contains characters other than ASCII letters and digits\n" "$password";;
*)
printf "%s only contains ASCII letters and digits\n" "$password";;
esac
(Notez que la déclaration à propos de ASCII lettres et chiffres est vraie pour le /bin/sh
d'Ubuntu, mais dans bash [:alnum:]
inclut toutes les lettres et tous les chiffres de l'environnement local actuel, pas seulement ceux ASCII .)
Ça sent terriblement comme un problème XY pour moi. Jamais, jamais, écrivez vos propres outils pour travailler avec des mots de passe. Au moins vous ne faites pas ici avec le stockage de mot de passe, mais la première chose qui me vient à l’esprit avec votre code est que je pourrais entrer un tout. -numeric password et le considérer comme "fort" (alors qu'en réalité, il serait beaucoup plus faible qu'un mot de passe alphabétique). Si vous continuez avec cette approche de la sécurité/gestion des mots de passe, vous allez tomber tôt ou tard et ce ne sera pas beau quand cela se produira.
La solution correcte consiste à utiliser une bibliothèque externe ou une application auxiliaire pour déterminer la force du mot de passe (et effectuer d'autres tâches associées à un mot de passe). De nos jours, la plupart des systèmes Linux ont PAM qui peut effectuer toutes les tâches liées à l'authentification de manière sécurisée (en prime, vous bénéficiez d'une assistance pour d'autres méthodes d'authentification en plus des mots de passe, en fonction de la configuration du système de l'utilisateur) et muru a déjà suggéré une application d'assistance qui détermine la force du mot de passe.
Voir
Générateur de mot de passe combinant des mots réels
"Mots de passe forts" ou "Force du processus de génération de mot de passe"
Comment puis-je appliquer une politique de complexité de mot de passe?
Vous pouvez uniquement vérifier certains aspects du mot de passe ou utiliser un outil spécifique à chaque méthode pour créer le mot de passe ou une méthode générale de force brute (si l'attaquant ne connaît pas la méthode).
pwdcheck
utilisant cracklib-check
#!/bin/bash
# setting variables
usage="Use 4 words chosen randomly, see this link:
https://security.stackexchange.com/questions/6095/xkcd-936-short-complex-password-or-long-dictionary-passphrase"
minlen=20 # can be modified here
short="is shorter than $minlen characters"
goodmix="is long enough"
badmix="is too short
$usage"
separator="-------"
# checking parameter
if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ $# -gt 1 ]; then
echo "${0##*/} uses 'cracklib-check'"
echo "----------------------------------------------------------------"
echo "Usage: $0 CandidateContaining4DifferentWords"
echo "Example: $0 At-least-$minlen-char"
echo " $0 'Should.be.selected.via.*random*.process'"
echo " $0 'Single-quote-for-1-special-character!'"
echo " $0 'FindPatternByDigitalTest123'"
echo " $0 'Provoke1pattern2search3by4separating5words'"
echo "$usage"
exit
Elif [ $# -eq 0 ]; then
echo "$usage"
echo "----------------------------------------------------------------"
read -p "Enter a password : " password
Elif [ $# -eq 1 ]; then
password="$1"
fi
# checking and installing if necessary
which cracklib-check > /dev/null
if [ $? -eq 1 ]; then
read -p "Do you want to install 'cracklib-runtime' to get 'cracklib-check'? (y/N) " ans
if [ "$ans" == "y" ]; then
Sudo apt-get update && Sudo apt-get install cracklib-runtime
fi
fi
if [ ${#password} -lt $minlen ]; then
result="$short"
else
result="$goodmix"
case "$password" in
*[![:alnum:]]*)
alnm="'$password' contains characters other than ASCII letters and digits";;
# result="$badmix";;
*)
alnm="$password contains only ASCII letters and digits";;
esac
fi
echo "Test 1 - size&mix: '$password' $result"
test ${#password} -lt $minlen || echo "$alnm"
if [ "$result" == "$badmix" ] || [ "$result" == "$short" ]; then
total="is bad"
else
total='is good'
fi
echo "$separator"
echo "Test 2 - Lexicon: '$password'"
sed -e 's/[0-9]/123\n/g' -e 's/$//' -e 's/[§!@£$€#¤%/()=?*,;.:_-~ ]/123\n/g' -e 's/$/123/g' \
<<< "$password" | LANG=C cracklib-check |sed 's/123: /: /'| \
grep 'it is based on a dictionary Word'
if [ $? -ne 0 ]; then
echo 'no comment'
fi
echo "$separator"
echo "Test 3 - digital: '$password'"
sed -e 's/[[:alpha:]]//g' -e 's/[§!@£$€#¤%/()=?*,;.:_-~ ]//g' -e 's/$/xyz/' \
<<< "$password" | LANG=C cracklib-check |sed 's/xyz: /: /'| \
grep 'it is too simplistic/systematic'
if [ $? -eq 0 ]; then
total='is bad'
else
echo 'is good'
fi
echo "$separator"
echo "Test 4 - cracklib-check: '$password'"
LANG=C cracklib-check <<< "$password" | tee /dev/stderr | grep ': OK' > /dev/null
if [ $? -eq 0 ]; then
echo='is good'
else
total='is bad'
fi
if [ "$total" == "is good" ]; then
echo "$separator"
ans=
while [ "$ans" != "g" ] && [ "$ans" != "b" ]
do
read -p "Test 5 - manual: Is '$password' a good or bad password? (g/b) " ans
if [ "$ans" == "g" ]; then
echo 'is good'
Elif [ "$ans" == "b" ]; then
total='is bad'
echo "$total"
fi
done
fi
echo "$separator"
if [ "$total" == "is good" ]; then
echo "Every test result for '$password' $total: No weakness found :-)"
else
echo "Some test result for '$password' $total: Some weakness found :-("
fi
En cours d'exécution dans le répertoire en cours, un répertoire de test. où vous avez le fichier shellscript,
$ ./pwdcheck -h
pwdcheck uses 'cracklib-check'
----------------------------------------------------------------
Usage: ./pwdcheck CandidateContaining4DifferentWords
Example: ./pwdcheck At-least-20-char
./pwdcheck 'Should.be.selected.via.*random*.process'
./pwdcheck 'Single-quote-for-1-special-character!'
./pwdcheck 'FindPatternByDigitalTest123'
./pwdcheck 'Provoke1pattern2search3by4separating5words'
Use 4 words chosen randomly, see this link:
https://security.stackexchange.com/questions/6095/xkcd-936-short-complex-password-or-long-dictionary-passphrase
$ apt-cache policy cracklib-runtime
cracklib-runtime:
Installerad: 2.9.2-1ubuntu1
Kandidat: 2.9.2-1ubuntu1
Versionstabell:
*** 2.9.2-1ubuntu1 500
500 http://se.archive.ubuntu.com/ubuntu xenial-updates/main i386 Packages
100 /var/lib/dpkg/status
2.9.2-1build2 500
500 http://se.archive.ubuntu.com/ubuntu xenial/main i386 Packages
Votre inspection manuelle et votre "test" peuvent être importants pour éviter les mots de passe vraiment mauvais, mais si vous utilisiez une méthode aléatoire automatique avec une bonne réputation, vous devriez vous y fier et éviter de falsifier le résultat , car vous ferez probablement en sorte que le mot de passe soit plus facile à déchiffrer.
$ ./pwdcheck CandidateContaining4DifferentWords
Test 1 - size&mix: 'CandidateContaining4DifferentWords' is long enough
CandidateContaining4DifferentWords contains only ASCII letters and digits
-------
Test 2 - Lexicon: 'CandidateContaining4DifferentWords'
no comment
-------
Test 3 - digital: 'CandidateContaining4DifferentWords'
is good
-------
Test 4 - cracklib-check: 'CandidateContaining4DifferentWords'
CandidateContaining4DifferentWords: OK
-------
Test 5 - manual: Is 'CandidateContaining4DifferentWords' a good or bad password? (g/b) b
is bad
-------
Some test result for 'CandidateContaining4DifferentWords' is bad: Some weakness found :-(
# comment: This password is published here!
##### Short password #####
$ ./pwdcheck At-least-20-char
Test 1 - size&mix: 'At-least-20-char' is shorter than 20 characters
-------
Test 2 - Lexicon: 'At-least-20-char'
least: it is based on a dictionary Word
char: it is based on a dictionary Word
-------
Test 3 - digital: 'At-least-20-char'
is good
-------
Test 4 - cracklib-check: 'At-least-20-char'
At-least-20-char: OK
-------
Some test result for 'At-least-20-char' is bad: Some weakness found :-(
##### Reminder about random process #####
$ ./pwdcheck 'Should.be.selected.via.*random*.process'
Test 1 - size&mix: 'Should.be.selected.via.*random*.process' is long enough
'Should.be.selected.via.*random*.process' contains characters other than ASCII letters and digits
-------
Test 2 - Lexicon: 'Should.be.selected.via.*random*.process'
Should: it is based on a dictionary Word
selected: it is based on a dictionary Word
via: it is based on a dictionary Word
random: it is based on a dictionary Word
process: it is based on a dictionary Word
-------
Test 3 - digital: 'Should.be.selected.via.*random*.process'
is good
-------
Test 4 - cracklib-check: 'Should.be.selected.via.*random*.process'
Should.be.selected.via.*random*.process: OK
-------
Test 5 - manual: Is 'Should.be.selected.via.*random*.process' a good or bad password? (g/b) g
is good
-------
Every test result for 'Should.be.selected.via.*random*.process' is good: No weakness found :-)
# comment: Do not use the password literally ;-)
##### Single quote the password, if you intend to use special characters #####
##### Words are found by Lexicon test (using cracklib-check), and accepted #####
$ ./pwdcheck 'Single-quote-for-1-special-character!'
Test 1 - size&mix: 'Single-quote-for-1-special-character!' is long enough
'Single-quote-for-1-special-character!' contains characters other than ASCII letters and digits
-------
Test 2 - Lexicon: 'Single-quote-for-1-special-character!'
Single: it is based on a dictionary Word
quote: it is based on a dictionary Word
for: it is based on a dictionary Word
special: it is based on a dictionary Word
character: it is based on a dictionary Word
-------
Test 3 - digital: 'Single-quote-for-1-special-character!'
is good
-------
Test 4 - cracklib-check: 'Single-quote-for-1-special-character!'
Single-quote-for-1-special-character!: OK
-------
Test 5 - manual: Is 'Single-quote-for-1-special-character!' a good or bad password? (g/b) b
is bad
-------
Some test result for 'Single-quote-for-1-special-character!' is bad: Some weakness found :-(
##### Showing how the digital test works (it uses cracklib-check) #####
$ ./pwdcheck 'FindPatternByDigitalTest123'
Test 1 - size&mix: 'FindPatternByDigitalTest123' is long enough
FindPatternByDigitalTest123 contains only ASCII letters and digits
-------
Test 2 - Lexicon: 'FindPatternByDigitalTest123'
no comment
-------
Test 3 - digital: 'FindPatternByDigitalTest123'
123: it is too simplistic/systematic
-------
Test 4 - cracklib-check: 'FindPatternByDigitalTest123'
FindPatternByDigitalTest123: OK
-------
Some test result for 'FindPatternByDigitalTest123' is bad: Some weakness found :-(
##### Showing the Lexicon test and the digital test #####
$ ./pwdcheck 'Provoke1pattern2search3by4separating5words'
Test 1 - size&mix: 'Provoke1pattern2search3by4separating5words' is long enough
Provoke1pattern2search3by4separating5words contains only ASCII letters and digits
-------
Test 2 - Lexicon: 'Provoke1pattern2search3by4separating5words'
Provoke: it is based on a dictionary Word
pattern: it is based on a dictionary Word
search: it is based on a dictionary Word
separating: it is based on a dictionary Word
words: it is based on a dictionary Word
-------
Test 3 - digital: 'Provoke1pattern2search3by4separating5words'
12345: it is too simplistic/systematic
-------
Test 4 - cracklib-check: 'Provoke1pattern2search3by4separating5words'
Provoke1pattern2search3by4separating5words: OK
-------
Some test result for 'Provoke1pattern2search3by4separating5words' is bad: Some weakness found :-(
##### Run interactively without any parameter #####
$ ./pwdcheck
Use 4 words chosen randomly, see this link:
https://security.stackexchange.com/questions/6095/xkcd-936-short-complex-password-or-long-dictionary-passphrase
----------------------------------------------------------------
Enter a password : CandidateContaining4DifferentWords
Test 1 - size&mix: 'CandidateContaining4DifferentWords' is long enough
CandidateContaining4DifferentWords contains only ASCII letters and digits
-------
Test 2 - Lexicon: 'CandidateContaining4DifferentWords'
no comment
-------
Test 3 - digital: 'CandidateContaining4DifferentWords'
is good
-------
Test 4 - cracklib-check: 'CandidateContaining4DifferentWords'
CandidateContaining4DifferentWords: OK
-------
Test 5 - manual: Is 'CandidateContaining4DifferentWords' a good or bad password? (g/b) g
is good
-------
Every test result for 'CandidateContaining4DifferentWords' is good: No weakness found :-)
sudodus@xenial32 /media/multimed-2/test/test0/pwdstrength $
td -d "[:alnum:]"
travaille pour moi:
$> echo '123§45!67M89(0' | tr -d "[:alnum:]"
§!(
Vous pouvez l'utiliser comme
#!/bin/bash
echo -n "Enter a password : "
read password
LEN=$(echo ${#password})
if [ $LEN -lt 10 ]; then
echo "$password is smaller than 10 characters"
else
if [ $(echo $password | tr -d "[:alnum:]" | wc -w) -eq 0 ]; then
echo "$password is a weak password"
else
echo "$password is a strong password"
fi
fi echo
wc -w
compte les mots.
Donc, si vous supprimez tous les alnum
et que le nombre de mots est 0
=> true => mot de passe faible
si le nombre de mots est 1
(ou plus si des espaces sont utilisés) => false => mot de passe fort