Problemas superficiais
Existem vários problemas com o seu script. Ele quebra se a senha contiver um número de caracteres especiais. Tente inserir entradas como:
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\
Leia Por que meu script de shell sufoca em espaço em branco ou outros caracteres especiais? . Tudo isso. Não escreva scripts de shell que estejam remotamente relacionados à segurança até que você entenda tudo isso.
Ah, e [:alnum:]
funciona perfeitamente. Você provavelmente pretendia escrever if [ -z …
ou if ! [ -n …
em vez de if ! [ -z …
.
Não existe a força de uma senha
A ideia de "força de senha" é um mito. É um mito que é espalhado por muitos sites, mas ainda é um mito. Não existe a força de uma senha, existe apenas a força de um processo de geração de senha .
Ter caracteres especiais em uma senha não o torna mais strong. Uma senha é um compromisso entre a facilidade de memorização e a facilidade de quebrar, e os caracteres especiais tornam as senhas significativamente mais difíceis de memorizar, mas não são significativamente mais difíceis de decifrar , conforme analisado em este tópico no Security Stack Exchange ( o conto , a matemática , alguns complementos - exercise: em esta resposta errada , quais partes ignoram completamente os fatos?). A ideia de que os caracteres especiais tornam uma senha mais strong baseia-se no pressuposto de que as pessoas que escrevem crackers de senha são idiotas. Adivinha o quê: eles não são. Há dinheiro para ganhar com a quebra de senhas, então você pode apostar que há pessoas que investem em fazê-lo bem.
Então, como devo escolher senhas?
Aleatoriamente . Se o seu método para escolher uma senha não incluir uma fonte de aleatoriedade (com um computador ou lançar um dado se você gostar da velha guarda), não é bom.
Diceware é uma escolha popular, mas qualquer método que siga o XKCD - escolhe várias “palavras” aleatoriamente de algum dicionário - é bom.
Um script correto
#!/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
Usar tr
desse modo supercomplica as coisas. O shell é perfeitamente capaz de verificar se uma string contém caracteres entre um determinado conjunto.
#!/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
(Observe que a declaração sobre ASCII letras e dígitos é verdadeira para /bin/sh
do Ubuntu, mas no bash [:alnum:]
inclui todas as letras e dígitos na localidade atual, não apenas os ASCII. )