Generierung eines zufälligen Passworts; Warum ist das nicht tragbar?

21

Ich möchte ein zufälliges Passwort generieren und mache es so:

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

Auf meinem Laptop, auf dem Ubuntu läuft, werden wie vorgesehen nur druckbare Zeichen erzeugt. Aber wenn ich in den Server meiner Schule, auf dem Red Hat Enterprise Linux ausgeführt wird, ssh und ihn dort ausführe, erhalte ich Ausgaben wie 3!ri�b�GrӴ��1�H�<�oM����&�nMC[�Pb�|L%MP�����9��fL2q���IFmsd|l�K, die überhaupt nicht funktionieren. Was könnte hier schief gehen?

Taymon
quelle

Antworten:

34

Es ist Ihre locale und tr Problem.

Derzeit unterstützt GNU tr nur Einzelbyte-Zeichen. In Gebietsschemas mit Multibyte-Codierungen kann die Ausgabe also komisch sein:

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

Die Shell druckt Multibyte-Zeichen korrekt aus, GNU trentfernt jedoch Bytes, die er für nicht druckbar hält.

Wenn es stabil sein soll, müssen Sie das Gebietsschema festlegen:

$ </dev/urandom LC_ALL=C tr -dc '[:print:]' | head -c 64
RSmuiFH+537z+iY4ySz`{Pv6mJg::RB;/-2^{QnKkImpGuMSq92D(6N8QF?Y9Co@
cuonglm
quelle
14
+1, weil mir klar wurde (ich benutze Shells unter Unix / Linux erst seit ungefähr 30 Jahren), dass die Umleitung stdin / stdout / stderr nicht nach dem Befehl positioniert werden muss, auf den sie angewendet wird.
Anthon
Nur ein Kommentar, wenn ein seltsames Gebietsschema festgelegt ist, sollte die Shell die Zeichen nicht trotzdem korrekt drucken können, auch wenn sie keine ASCII-Zeichen sind? Zumindest eine kompetente Shell (ohne xterm natürlich)?
Orion
2
@orion: Die Shell druckt die Zeichen korrekt aus. In diesem Fall ist das ein Problem. Es entfernt Bytes, die es für nicht druckbar hält, und macht das Ergebnis seltsam.
Dienstag,
@orion Ein gleichmäßig zufälliger Strom von Bytes ist im Allgemeinen kein gleichmäßig zufälliger Strom von wohlgeformten UTF-8-Zeichencodierungen .
Sonntag,
Außerdem sollten Sie :graph:anstelle von :print::</dev/urandom LC_ALL=C tr -dc '[:graph:]' | head -c 64
edan
11

Betrachten Sie stattdessen

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

Das hat zwei Vorteile:

  • Sie lesen nur 48 Bytes vom zufälligen Gerät, nicht ~ 8 KB; Wenn andere Prozesse auf demselben Host Zufallszahlen benötigen, kann die gleichzeitige Entleerung von 8 KB ein ernstes Problem sein. (Ja, wohl sollte niemand das blockierende Zufallsgerät verwenden, aber die Leute tun es .)

  • Die Ausgabe von base64enthält fast keine Sonderzeichen. (Für gar keinen, tack | tr +/ -_am Ende, und (wie im Beispiel) stellen Sie sicher , die Anzahl von Bytes Eingang zu base64einem Vielfach von 3)

Ein auf diese Weise generiertes Passwort hat genau 384 Entropiebits, was etwas weniger ist als das, was Sie getan haben (log 2 96 64 ≈ 421.4), aber für die meisten Zwecke mehr als genug (256 Entropiebits sind sicher in "noch zu erraten, wann die Sonne brennt aus "Gebiet mit Ausnahme von RSA-Schlüsseln (AFAIK).

zwol
quelle
3

Andere Leute haben bereits darauf hingewiesen, dass das Gebietsschema bestimmt, was [:print:]bedeutet. Allerdings sind nicht alle druckbaren Zeichen für Passwörter geeignet (auch nicht in ASCII). Sie möchten wirklich keine Leerzeichen, Tabulatoren und # $% ^? in Ihrem Passwort - es ist nicht nur schwer zu merken, es ist auch potentiell gefährlich für das zugrunde liegende Authentifizierungssystem, es kann unmöglich sein, in ein Eingabefeld zu gelangen, und so weiter. In diesem Fall sollten Sie "gesunde" Zeichen nur manuell auswählen:

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

oder einfach

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

Oder noch besser, base64wie in anderen Antworten vorgeschlagen.

orion
quelle
Das fragliche Passwort wird niemals von Menschen eingegeben (wenn ich stattdessen Diceware verwenden würde), und ich bin mir ziemlich sicher, dass das zugrunde liegende System Sonderzeichen problemlos verarbeiten kann. Danke trotzdem.
Taymon
4
Was Sie sagen, ist völlig falsch. Das Erzwingen, dass Benutzer nur ASCII-Buchstaben, -Ziffern und -Unterstriche verwenden, verringert die Alphabetgröße erheblich, wodurch das Auflösen von Kennwörtern für Angreifer erheblich vereinfacht wird. Ein Authentifizierungssystem, das nicht einmal damit umgehen kann ?oder ^einfach zu schlecht ist, um ernst genommen zu werden.
Bakuriu
2
Wenn Ihr Authentifizierungssystem oder Ihre Eingabefelder an normalen ASCII-Symbolen verstopfen ... dann tun Sie etwas falsch und dürfen meinen privaten Informationen nicht trauen. Es gibt absolut keinen Grund, alle Arten von Zeichen (einschließlich Leerzeichen) in Ihren Passwörtern nicht zu akzeptieren.
nzifnab
2
Dies scheint hier nicht der Fall zu sein, aber wenn es um Eingaben von Menschen geht, ist es viel einfacher, sich ein langes alphanumerisches Passwort zu merken, das für den Besitzer eine eindeutige Bedeutung hat, als ein kürzeres Durcheinander von Symbolen. Es gibt auch das Problem, diese Zeichen auf verschiedenen Tastaturen einzugeben (nicht jeder hat ^ in der ersten Ebene und die meisten Leute wissen nicht einmal, wo oder was ein Backtick ist), Eingabefelder können das Tabulatorzeichen mit ziemlicher Sicherheit nicht verarbeiten und a Eine überraschende Anzahl von Webformularen ist immer noch anfällig für Validierungsfehler, SQL-Injection oder sogar für unsichere Groß- und Kleinschreibung.
Orion
1
Nur ein Hinweis: in C locale [:print:]Klasse ist nicht enthalten Registerkarten. Es ist nur ein [:alnum:]+ [:punct:]+ Leerzeichen ( kein Leerzeichen [:space:]).
Jimmy
2

Wie wäre es mit

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

Zeichenfolgen sollten die Ausgabe von urandom in einem druckbaren Format drucken

Blindstealer
quelle
Dies gibt-bash: /dev/urandom: Permission denied
Anthon
Entschuldigung, habe die
Hauptkatze
2

Ich weiß nicht, ob es einen Grund gibt, warum Sie /dev/randomdas Passwort generieren, aber ich würde Ihnen empfehlen, pwgen zu verwenden, um Ihre Schmerzen zu lindern.

$ pwgen -s 10 1

Wobei 10 die Länge des Passworts ist.

http://man.cx/pwgen

Daniel
quelle
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

Diese Methode ist intelligenter, wenn Daten aus / dev / urandom verwendet werden. Die als $ P $ P $ P ... eingefügte Zeichenfolge muss mindestens 256 Zeichen lang sein.

Alexander Kelner
quelle