ランダムパスワードの生成。なぜこのポータブルではないのですか?


21

ランダムなパスワードを生成したいので、次のようにしています:

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

Ubuntuを実行しているラップトップでは、意図したとおりに印刷可能な文字のみが生成されます。しかし、Red Hat Enterprise Linuxを実行している学校のサーバーにsshし、そこで実行すると、のような出力が得られますが3!ri�b�GrӴ��1�H�<�oM����&�nMC[�Pb�|L%MP�����9��fL2q���IFmsd|l�K、まったく実行されません。ここで何が間違っているのでしょうか?

回答:


34

それはあなたのロケールtrの問題です。

現在、GNU trはシングルバイト文字のみを完全にサポートしています。したがって、マルチバイトエンコーディングを使用するロケールでは、出力がおかしくなる可能性があります。

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

シェルはマルチバイト文字を正しく印刷しますが、GNU trは印刷不可能と思われるバイトを削除します。

安定させるには、ロケールを設定する必要があります。

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

14
+1になったため(Unix / Linuxでシェルを約30年間しか使用していなかったため)、stdin / stdout / stderrリダイレクトを適用するコマンドのに配置する必要がないことがわかりました。
アントン

奇妙なロケールが設定されている場合、コメントだけで、たとえASCIIでなくても、シェルは文字を正しく印刷できるはずではありませんか?少なくとも有能なシェル(もちろんxtermを除く)?
オリオン

2
@orion:シェルは文字を正しく印刷します。この場合、それはtrの問題です。印刷不可能と思われるバイトを削除し、結果を奇妙にしました。
cuonglm

@orion一般に、バイトの一様にランダムなストリームは、整形式のUTF-8文字エンコードの一様にランダムなストリームではありません。
zwol

また、あなたがない限り、パスワードでどのようなスペースは、あなたが使用する必要があります:graph:代わりに:print:</dev/urandom LC_ALL=C tr -dc '[:graph:]' | head -c 64
エダン

11

代わりに検討してください

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

これには2つの利点があります。

  • ランダムデバイスから読み取るのは48 KBのみであり、8 KB以下です。同じホスト上の他のプロセスが乱数を必要とする場合、8KBが一度に消費されることが深刻な問題になる可能性があります。(はい、おそらく誰もブロッキングランダムデバイスを使用すべきではありませんが、人々はそうします。)

  • の出力にbase64は、特別な意味を持つ文字はほとんど含まれていません。(まったくない場合| tr +/ -_は、最後にタックし、(例のように)入力するバイト数base64が3の倍数であることを確認します。)

このように生成されたパスワードは、エントロピーの正確384ビットあり、多少あなたは何をしていたよりも少ない(ログイン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、他の回答で提案されているとおりに使用してください。


問題のパスワードが人間によって入力されることは決してありません(代わりにDicewareを使用している場合)、基になるシステムは問題なく特殊文字を処理できると確信しています。とにかくありがとう。
タイモン

4
あなたの言うことは全く間違っています。ユーザーにASCII文字、数字、アンダースコアのみを使用するように強制すると、アルファベットのサイズが大幅に縮小され、攻撃者のパスワードを解読しやすくなります。処理することさえできない、?または^真剣に考えるにはあまりにも悪い認証システム。
バクリウ

2
あなたの認証システムまたは入力フィールドが通常のASCIIシンボルで詰まっている場合...あなたは何か間違ったことをしていて、私の個人情報で信頼されるべきではありません。パスワードにあらゆる種類の文字(スペースを含む)を受け入れない理由はまったくありません。
nzifnab

2
ここではそうではないようですが、人間の入力に関しては、短いごちゃ混ぜのシンボルよりも所有者にとってユニークな意味を持つ長い英数字のパスワードを覚える方がはるかに簡単です。さまざまなキーボードでこれらの文字を入力する問題もあります(すべての人が最初のレベルに^を持っているわけではなく、ほとんどの人はバックティックがどこにあるか何もわからない)。驚くほど多くのWebフォームがまだ検証エラー、SQLインジェクション、または不確実な大文字と小文字の区別の影響を受けやすくなっています。
オリオン

1
注:Cロケール[:print:]クラスにはタブ含まれませ。スペースは[:alnum:]+ [:punct:]+ のみです(単一スペースではなく [:space:])。
-jimmij

2

どう?

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

文字列はurandomの出力を印刷可能な形式で印刷する必要があります


これにより-bash: /dev/urandom: Permission denied
Anthon

申し訳ありません有数猫忘れてしまった
Blindstealer

2

/dev/randomパスワードの生成に使用する理由があるかどうかはわかりませんが、痛みを和らげるためにpwgenを使用することをお勧めします。

$ pwgen -s 10 1

ここで、10はパスワードの長さです。

http://man.cx/pwgen


1
#Chars allowed in password (I don't like l,o,O, etc):
P="0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz"

#Or such:
#P="a-zA-Z0-9"

head -c 8 < /dev/urandom | tr '\000-\377' "$P$P$P$P$P"
echo

このメソッドは、/ dev / urandomからデータを消費する場合、より賢くなります。$ P $ P $ P ...として貼り付ける文字列は、少なくとも256文字の長さが必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.