生成随机密码;为什么这个不便携?

生成随机密码;为什么这个不便携?

我想生成一个随机密码,并且这样做:

</dev/urandom tr -dc [:print:] | head -c 64

在我运行 Ubuntu 的笔记本电脑上,这仅产生可打印的字符,正如预期的那样。但是,当我 ssh 进入学校的服务器(运行 Red Hat Enterprise Linux)并在那里运行它时,我得到类似 的输出3!ri�b�GrӴ��1�H�<�oM����&�nMC[�Pb�|L%MP�����9��fL2q���IFmsd|l�K,这根本不起作用。这里可能出了什么问题?

答案1

是你的语言环境t问题。

现在,GNU TR仅完全支持单字节字符。因此,在使用多字节编码的语言环境中,输出可能会很奇怪:

$ </dev/urandom LC_ALL=vi_VN.tcvn tr -dc '[:print:]' | head -c 64
`�pv���Z����c�ox"�O���%�YR��F�>��췔��ovȪ������^,<H ���>

shell 将正确打印多字节字符,但 GNUtr将删除它认为不可打印的字节。

如果你想让它稳定,你必须设置语言环境:

$ </dev/urandom LC_ALL=C tr -dc '[:print:]' | head -c 64
RSmuiFH+537z+iY4ySz`{Pv6mJg::RB;/-2^{QnKkImpGuMSq92D(6N8QF?Y9Co@

答案2

考虑一下

$ dd if=/dev/urandom bs=48 count=1 status=none | base64
imW/X60Sk9TQzl+mdS5PL7sfMy9k/qFBWWkzZjbYJttREsYpzIguWr/uRIhyisR7

这样做有两个优点:

  • 您从随机设备中仅读取了 48 个字节,而不是 ~8KB;如果同一主机上的其他进程需要随机数,那么一次性耗尽 8KB 可能会是一个严重的问题。 (是的,可以说没有人应该使用阻塞随机设备,但人.)

  • 的输出base64几乎不包含具有特殊含义的字符。 (如果根本没有,请| tr +/ -_在末尾添加,并(如示例中所示)确保字节数输入tobase64是 3 的倍数。)

以这种方式生成的密码正好有 384 位的熵,即有些比你正在做的要少(log 2 96 64 ≈ 421.4),但对于大多数目的来说已经足够了(256位熵安全地处于“仍在猜测太阳何时燃烧殆尽”的范围内除了对于 RSA 密钥,据我所知)。

答案3

其他人已经指出,区域设置决定了[:print:]含义。然而,并非所有可打印字符都适合作为密码(甚至在 ascii 中也不适用)。您真的不需要空格、制表符和#$%^ 吗?在您的密码中 - 它不仅难以记住,而且对底层身份验证系统也存在潜在危险,可能无法在输入字段中输入,等等。在这种情况下,您应该手动选择“正常”字符:

LC_ALL=C </dev/urandom tr -dc '[:alnum:]_' | head -c 64

或者简单地

</dev/urandom tr -dc 'A-Za-z0-9_' | head -c 64

或者更好的是,base64按照其他答案中的建议使用。

答案4

我不知道您是否有任何理由使用/dev/random它来生成密码,但我建议您使用 pwgen 以减轻您的痛苦。

$ pwgen -s 10 1

其中 10 是密码的长度。

http://man.cx/pwgen

相关内容