Pan*_*ael 6 command-line password text-processing
我写了这个脚本但[:alnum:]
不起作用。有人帮忙吗?
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
Run Code Online (Sandbox Code Playgroud)
mur*_*uru 16
如果你真的想检查密码强度,你应该cracklib-check
从cracklib-runtime
包中使用(默认情况下应该安装):
$ 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
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 13
您的脚本有几个问题。如果密码包含许多特殊字符,则会中断。尝试输入输入,例如:
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\
Run Code Online (Sandbox Code Playgroud)
阅读为什么我的 shell 脚本会因空格或其他特殊字符而阻塞?. 所有的。在您完全理解之前,不要编写任何与安全性相关的 shell 脚本。
哦,而且[:alnum:]
效果很好。您可能打算编写if [ -z …
或if ! [ -n …
代替if ! [ -z …
.
“密码强度”的想法是一个神话。这是一个被很多网站传播的神话,但它仍然是一个神话。没有密码强度这样的东西,只有密码生成过程的强度。
在密码中包含特殊字符并不会使其更强大。密码是易于记忆和易于破解之间的折衷,特殊字符使密码更难记忆,但并不明显更难破解,正如Security Stack Exchange 上的这个帖子所分析的(短篇小说,数学,一些补充-练习:在这个错误的答案中,哪些部分完全无视事实?)。特殊字符使密码更强大的想法是基于这样的假设:编写密码破解程序的人是白痴。你猜怎么着:他们不是。破解密码可以赚钱,所以你可以打赌有人投资做得很好。
随机。如果您选择密码的方法不包括随机源(使用计算机,或者如果您喜欢老式的掷骰子),那就不好了。
Diceware是一种流行的选择,但任何遵循XKCD 模式的方法——从某个字典中随机挑选多个“单词”——都是好的。
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\
Run Code Online (Sandbox Code Playgroud)
tr
以这种方式使用会使事情变得过于复杂。shell 完全能够检查字符串是否包含某个集合中的字符。
#!/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
Run Code Online (Sandbox Code Playgroud)
(请注意,关于ASCII字母和数字的声明对于 Ubuntu 是正确的/bin/sh
,但在 bash 中[:alnum:]
包括当前语言环境中的所有字母和数字,而不仅仅是 ASCII 字母和数字。)
对我来说闻起来很像 XY 问题。永远不要编写自己的工具来处理密码。至少您没有在这里处理密码存储,但是您的代码首先想到的是我可以输入一个全数字密码并将其视为“强”(实际上它会弱很多而不是全字母密码)。如果您继续采用这种安全性/密码处理方法,您迟早会跌倒,而且当它发生时不会很漂亮。
正确的解决方案是使用外部库或辅助应用程序来确定密码强度(并执行其他与密码相关的任务)。现在大多数 Linux 系统都有 PAM,可以以安全的方式为您执行所有与身份验证相关的任务(作为奖励,除了密码之外,您还可以获得对其他身份验证方法的支持,具体取决于用户系统的配置方式),并且 muru 已经建议了一个确定密码强度的辅助应用程序。
看
\n\n\n\n\n\n您只能检查密码的某些方面,或者使用每种方法的特定工具来创建密码或使用一般的暴力方法(如果攻击者不知道该方法)。
\n\npwdcheck
使用cracklib-check
#!/bin/bash\n\n# setting variables\n\nusage="Use 4 words chosen randomly, see this link:\nhttps://security.stackexchange.com/questions/6095/xkcd-936-short-complex-password-or-long-dictionary-passphrase"\n\nminlen=20 # can be modified here\nshort="is shorter than $minlen characters"\ngoodmix="is long enough"\nbadmix="is too short\n$usage"\nseparator="-------"\n\n# checking parameter\n\nif [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ $# -gt 1 ]; then\n echo "${0##*/} uses \'cracklib-check\'"\n echo "----------------------------------------------------------------"\n echo "Usage: $0 CandidateContaining4DifferentWords"\n echo "Example: $0 At-least-$minlen-char"\n echo " $0 \'Should.be.selected.via.*random*.process\'"\n echo " $0 \'Single-quote-for-1-special-character!\'"\n echo " $0 \'FindPatternByDigitalTest123\'"\n echo " $0 \'Provoke1pattern2search3by4separating5words\'"\n echo "$usage"\n exit\nelif [ $# -eq 0 ]; then\n echo "$usage"\n echo "----------------------------------------------------------------"\n read -p "Enter a password : " password\nelif [ $# -eq 1 ]; then\n password="$1"\nfi\n\n# checking and installing if necessary\n\nwhich cracklib-check > /dev/null\nif [ $? -eq 1 ]; then\n read -p "Do you want to install \'cracklib-runtime\' to get \'cracklib-check\'? (y/N) " ans\n if [ "$ans" == "y" ]; then\n sudo apt-get update && sudo apt-get install cracklib-runtime\n fi\nfi\n\nif [ ${#password} -lt $minlen ]; then\n result="$short"\nelse\n result="$goodmix"\n case "$password" in\n *[![:alnum:]]*)\n alnm="\'$password\' contains characters other than ASCII letters and digits";;\n# result="$badmix";;\n *)\n alnm="$password contains only ASCII letters and digits";;\n esac\nfi\n\necho "Test 1 - size&mix: \'$password\' $result"\ntest ${#password} -lt $minlen || echo "$alnm"\nif [ "$result" == "$badmix" ] || [ "$result" == "$short" ]; then\n total="is bad"\nelse\n total=\'is good\'\nfi\n\necho "$separator"\necho "Test 2 - lexicon: \'$password\'"\nsed -e \'s/[0-9]/123\\n/g\' -e \'s/$//\' -e \'s/[\xc2\xa7!@\xc2\xa3$\xe2\x82\xac#\xc2\xa4%/()=?*,;.:_-~ ]/123\\n/g\' -e \'s/$/123/g\' \\\n<<< "$password" | LANG=C cracklib-check |sed \'s/123: /: /\'| \\\ngrep \'it is based on a dictionary word\'\nif [ $? -ne 0 ]; then\n echo \'no comment\'\nfi\n\necho "$separator"\necho "Test 3 - digital: \'$password\'"\nsed -e \'s/[[:alpha:]]//g\' -e \'s/[\xc2\xa7!@\xc2\xa3$\xe2\x82\xac#\xc2\xa4%/()=?*,;.:_-~ ]//g\' -e \'s/$/xyz/\' \\\n<<< "$password" | LANG=C cracklib-check |sed \'s/xyz: /: /\'| \\\ngrep \'it is too simplistic/systematic\'\nif [ $? -eq 0 ]; then\n total=\'is bad\'\nelse\n echo \'is good\'\nfi\n\necho "$separator"\necho "Test 4 - cracklib-check: \'$password\'"\nLANG=C cracklib-check <<< "$password" | tee /dev/stderr | grep \': OK\' > /dev/null\nif [ $? -eq 0 ]; then\n echo=\'is good\'\nelse\n total=\'is bad\'\nfi\n\nif [ "$total" == "is good" ]; then\n echo "$separator"\n ans=\n while [ "$ans" != "g" ] && [ "$ans" != "b" ]\n do\n read -p "Test 5 - manual: Is \'$password\' a good or bad password? (g/b) " ans\n if [ "$ans" == "g" ]; then\n echo \'is good\'\n elif [ "$ans" == "b" ]; then\n total=\'is bad\'\n echo "$total"\n fi\n done\nfi\n\necho "$separator"\nif [ "$total" == "is good" ]; then\n echo "Every test result for \'$password\' $total: No weakness found :-)"\nelse\n echo "Some test result for \'$password\' $total: Some weakness found :-("\nfi\n
Run Code Online (Sandbox Code Playgroud)\n\n在当前目录中运行,测试目录。你有 shellscript 文件的地方,
\n\n$ ./pwdcheck -h\npwdcheck uses \'cracklib-check\'\n----------------------------------------------------------------\nUsage: ./pwdcheck CandidateContaining4DifferentWords\nExample: ./pwdcheck At-least-20-char\n ./pwdcheck \'Should.be.selected.via.*random*.process\'\n ./pwdcheck \'Single-quote-for-1-special-character!\'\n ./pwdcheck \'FindPatternByDigitalTest123\'\n ./pwdcheck \'Provoke1pattern2search3by4separating5words\'\nUse 4 words chosen randomly, see this link:\nhttps://security.stackexchange.com/questions/6095/xkcd-936-short-complex-password-or-long-dictionary-passphrase\n
Run Code Online (Sandbox Code Playgroud)\n\n$ apt-cache policy cracklib-runtime \ncracklib-runtime:\n Installerad: 2.9.2-1ubuntu1\n Kandidat: 2.9.2-1ubuntu1\n Versionstabell:\n *** 2.9.2-1ubuntu1 500\n 500 http://se.archive.ubuntu.com/ubuntu xenial-updates/main i386 Packages\n 100 /var/lib/dpkg/status\n 2.9.2-1build2 500\n 500 http://se.archive.ubuntu.com/ubuntu xenial/main i386 Packages\n
Run Code Online (Sandbox Code Playgroud)\n\n您的手动检查和“测试”对于避免真正糟糕的密码可能很重要,\n但是如果您使用了声誉良好的自动随机方法,则应该\n依赖它并避免篡改结果,因为您可能会密码\更容易被破解。
\n\n$ ./pwdcheck CandidateContaining4DifferentWords\nTest 1 - size&mix: \'CandidateContaining4DifferentWords\' is long enough\nCandidateContaining4DifferentWords contains only ASCII letters and digits\n-------\nTest 2 - lexicon: \'CandidateContaining4DifferentWords\'\nno comment\n-------\nTest 3 - digital: \'CandidateContaining4DifferentWords\'\nis good\n-------\nTest 4 - cracklib-check: \'CandidateContaining4DifferentWords\'\nCandidateContaining4DifferentWords: OK\n-------\nTest 5 - manual: Is \'CandidateContaining4DifferentWords\' a good or bad password? (g/b) b\nis bad\n-------\nSome test result for \'CandidateContaining4DifferentWords\' is bad: Some weakness found :-(\n# comment: This password is published here!\n\n##### Short password #####\n\n$ ./pwdcheck At-least-20-char\nTest 1 - size&mix: \'At-least-20-char\' is shorter than 20 characters\n-------\nTest 2 - lexicon: \'At-least-20-char\'\nleast: it is based on a dictionary word\nchar: it is based on a dictionary word\n-------\nTest 3 - digital: \'At-least-20-char\'\nis good\n-------\nTest 4 - cracklib-check: \'At-least-20-char\'\nAt-least-20-char: OK\n-------\nSome test result for \'At-least-20-char\' is bad: Some weakness found :-(\n\n##### Reminder about random process #####\n\n$ ./pwdcheck \'Should.be.selected.via.*random*.process\'\nTest 1 - size&mix: \'Should.be.selected.via.*random*.process\' is long enough\n\'Should.be.selected.via.*random*.process\' contains characters other than ASCII letters and digits\n-------\nTest 2 - lexicon: \'Should.be.selected.via.*random*.process\'\nShould: it is based on a dictionary word\nselected: it is based on a dictionary word\nvia: it is based on a dictionary word\nrandom: it is based on a dictionary word\nprocess: it is based on a dictionary word\n-------\nTest 3 - digital: \'Should.be.selected.via.*random*.process\'\nis good\n-------\nTest 4 - cracklib-check: \'Should.be.selected.via.*random*.process\'\nShould.be.selected.via.*random*.process: OK\n-------\nTest 5 - manual: Is \'Should.be.selected.via.*random*.process\' a good or bad password? (g/b) g\nis good\n-------\nEvery test result for \'Should.be.selected.via.*random*.process\' is good: No weakness found :-)\n# comment: Do not use the password literally ;-)\n\n##### Single quote the password, if you intend to use special characters #####\n##### Words are found by lexicon test (using cracklib-check), and accepted #####\n\n$ ./pwdcheck \'Single-quote-for-1-special-character!\'\nTest 1 - size&mix: \'Single-quote-for-1-special-character!\' is long enough\n\'Single-quote-for-1-special-character!\' contains characters other than ASCII letters and digits\n-------\nTest 2 - lexicon: \'Single-quote-for-1-special-character!\'\nSingle: it is based on a dictionary word\nquote: it is based on a dictionary word\nfor: it is based on a dictionary word\nspecial: it is based on a dictionary word\ncharacter: it is based on a dictionary word\n-------\nTest 3 - digital: \'Single-quote-for-1-special-character!\'\nis good\n-------\nTest 4 - cracklib-check: \'Single-quote-for-1-special-character!\'\nSingle-quote-for-1-special-character!: OK\n-------\nTest 5 - manual: Is \'Single-quote-for-1-special-character!\' a good or bad password? (g/b) b\nis bad\n-------\nSome test result for \'Single-quote-for-1-special-character!\' is bad: Some weakness found :-(\n\n##### Showing how the digital test works (it uses cracklib-check) #####\n\n$ ./pwdcheck \'FindPatternByDigitalTest123\'\nTest 1 - size&mix: \'FindPatternByDigitalTest123\' is long enough\nFindPatternByDigitalTest123 contains only ASCII letters and digits\n-------\nTest 2 - lexicon: \'FindPatternByDigitalTest123\'\nno comment\n-------\nTest 3 - digital: \'FindPatternByDigitalTest123\'\n123: it is too simplistic/systematic\n-------\nTest 4 - cracklib-check: \'FindPatternByDigitalTest123\'\nFindPatternByDigitalTest123: OK\n-------\nSome test result for \'FindPatternByDigitalTest123\' is bad: Some weakness found :-(\n\n##### Showing the lexicon test and the digital test #####\n\n$ ./pwdcheck \'Provoke1pattern2search3by4separating5words\'\nTest 1 - size&mix: \'Provoke1pattern2search3by4separating5words\' is long enough\nProvoke1pattern2search3by4separating5words contains only ASCII letters and digits\n-------\nTest 2 - lexicon: \'Provoke1pattern2search3by4separating5words\'\nProvoke: it is based on a dictionary word\npattern: it is based on a dictionary word\nsearch: it is based on a dictionary word\nseparating: it is based on a dictionary word\nwords: it is based on a dictionary word\n-------\nTest 3 - digital: \'Provoke1pattern2search3by4separating5words\'\n12345: it is too simplistic/systematic\n-------\nTest 4 - cracklib-check: \'Provoke1pattern2search3by4separating5words\'\nProvoke1pattern2search3by4separating5words: OK\n-------\nSome test result for \'Provoke1pattern2search3by4separating5words\' is bad: Some weakness found :-(\n\n##### Run interactively without any parameter #####\n\n$ ./pwdcheck\nUse 4 words chosen randomly, see this link:\nhttps://security.stackexchange.com/questions/6095/xkcd-936-short-complex-password-or-long-dictionary-passphrase\n----------------------------------------------------------------\nEnter a password : CandidateContaining4DifferentWords\nTest 1 - size&mix: \'CandidateContaining4DifferentWords\' is long enough\nCandidateContaining4DifferentWords contains only ASCII letters and digits\n-------\nTest 2 - lexicon: \'CandidateContaining4DifferentWords\'\nno comment\n-------\nTest 3 - digital: \'CandidateContaining4DifferentWords\'\nis good\n-------\nTest 4 - cracklib-check: \'CandidateContaining4DifferentWords\'\nCandidateContaining4DifferentWords: OK\n-------\nTest 5 - manual: Is \'CandidateContaining4DifferentWords\' a good or bad password? (g/b) g\nis good\n-------\nEvery test result for \'CandidateContaining4DifferentWords\' is good: No weakness found :-)\nsudodus@xenial32 /media/multimed-2/test/test0/pwdstrength $ \n
Run Code Online (Sandbox Code Playgroud)\n
Pan*_*ael -3
我找到了正确的脚本并且它有效:
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 '[:alpha:]' | tr -d '[:upper:]' | tr -d '[:lower:]' ` ]; then
echo "$password is a weak password"
else
echo "$password is a strong password"
fi
fi
echo
Run Code Online (Sandbox Code Playgroud)