Warum kann unter OSX nicht aus / dev / urandom gelesen werden?

35

Ein Kollege schlug vor, mit dem folgenden Befehl einen zufälligen Schlüssel zu erstellen:

tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs

Es gab mir den Fehler:

tr: Unzulässige Bytefolge

Ich mache mir Sorgen, dass ich nicht /dev/urandomauf meinem System habe. Ich habe versucht zu googeln, um herauszufinden, wie man diese Datei installiert, aber ich bin leer ausgekommen. Ich habe es versucht locate urandomund bin auch leer gekommen. (Nun, eigentlich hat es die Manpage gefunden, aber das hilft nicht)

Wie stelle ich urandomauf meinem Mac OSX-System zur Verfügung? (Löwe)

Kirk Woll
quelle
3
Interessante Verwendung von xargs...
sendmoreinfo

Antworten:

49

Anhand der Fehlermeldung, die Sie erhalten, glaube ich nicht, dass / dev / urandom das Problem ist. Wenn es so wäre, würde ich einen Fehler wie "keine solche Datei oder Verzeichnis" erwarten.

Ich habe nach der Fehlermeldung gesucht, die Sie erhalten haben, und habe diese gefunden, die möglicherweise für Ihr Problem relevant ist: http://nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence

Geben Sie das Gebietsschema an, indem Sie dem trBefehl Folgendes voranstellen LC_CTYPE=C:

LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
lk-
quelle
Danke, das hat den Trick gemacht. Irgendeine Idee, warum ich nicht finden kann urandomoder random? Handelt es sich um spezielle magische "Dateien", die im tatsächlichen Dateisystem nicht vorhanden sind? (Ich schlug auch eine Änderung vor, um Link-Rot zu mildern)
Kirk Woll
1
Ich glaube, locatedass Ihr Dateisystem nicht direkt durchsucht wird, sondern dass Ihre Abfrage mithilfe einer vorgefertigten Datenbank nachgeschlagen wird. Diese Datenbank ist höchstwahrscheinlich so konfiguriert, dass sie / dev / und andere "spezielle" Dateisysteme ignoriert.
13.08.12
fair genug, aber ich sehe es nicht, wenn ich direkt hineinschaue /dev. Stelle dir das vor. Aber nochmals vielen Dank für die Hilfe.
Kirk Woll
1
scheint nicht mit 10.9 zu funktionieren; schlägt immer noch mit der gleichen Fehlermeldung fehl. LC_ALL=Cmacht den Trick tho.
Erik Allik
1
Bitte ändern Sie diesen Link zu nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence, da er derzeit auf die neueste Blog-Seite verweist, die die trInformationen nicht enthält .
Jeroen Wiert Pluimers
11

Ihre trVersuche, die Eingabe als Text in UTF-8-Codierung zu interpretieren. Daher wird die erste Byte-Sequenz, die nicht für UTF-8 gültig ist, beanstandet und abgebrochen. Das Präfixieren trmit LC_ALL=Coder LC_CTYPE=Cexportiert diese Variable in die Umgebung von trund ändert damit ihre Vorstellung vom lokalen Zeichensatz in den C-Standard, dh alles ist nur eine Folge von undurchsichtigen Bytes.

Ist die Reihenfolge \)-+in Ihrem Befehl übrigens beabsichtigt? Dies schließt *auch ein, was Sie bereits einbezogen haben, sich jedoch nicht so ein -, wie Sie es beabsichtigt haben. Schreiben Sie stattdessen lieber eine dieser Zeilen:

LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom
MvG
quelle
6

Wie andere schon angedeutet haben, ist Ihr Problem nicht , das /dev/urandomfehlt, sondern vielmehr , wie trfunktioniert auf OS X. Statt mit enviornment Herumspielen varialbes, Verwendung perlanstelle von tr:

perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo

Dies hat den Vorteil, dass es auf OS X, Redhat und Ubuntu portierbar ist.

(Ich habe auch die Pipe entfernt xargs, um Hexe zu ersetzen echo, um eine neue Zeile am Ende der Ausgabe zu erhalten.)

Trenton
quelle
Ich gehe davon aus, dass Perl früher oder später zum binmode ":utf8"Standard wird. Zu diesem Zeitpunkt wird Ihre Perl-Lösung das gleiche Problem haben trwie früher.
Mark
Behebung von Marks Bedenken durch Hinzufügen von binmode (STDIN, ": bytes") zum Codebeispiel.
Trenton
2

Wollten Sie erstens gültige Zeichen aufnehmen -oder *in die Liste aufnehmen? Der Parameter, trder die Sequenz enthält, )-+die "den Byte-Bereich beginnend mit )und endend mit" bedeutet +, der tatsächlich ist )*+.

Zweitens, anstatt viele Kilobyte aus der Kernel-Entropie - Pool zu lesen (und damit den gesamten Pool als unsicher markiert, die andere Prozesse auswirken, die eine sichere Entropie benötigen), sollten nur so viele Bits zu lesen , wie Sie benötigen: Verwendung head -c...als ersten Schritt, und dann eher übersetzen als unerwünschte Zeichen zu verwerfen.

Diese spezielle Version des Problems ist etwas ungewöhnlich, da 76 verschiedene Symbole verwendet werden. Die meisten möchten nur alphanumerische Zeichen. Wenn Sie also mit nur 64 Symbolen zufrieden sind, base64minimiert die Verwendung des Dienstprogramms den Verbrauch des Entropiepools (beachten Sie, dass 24 6/8 von 32 ist):

head -c24 < /dev/random | base64
Martin Kealey
quelle
1

Die Zeichencodierung Ihres Gebietsschemas (die Sie erkennen können locale charmap) besteht aus einem Multi-Byte pro Zeichen.

Heutzutage ist UTF-8 am gebräuchlichsten, bei dem Zeichen über 1 bis 4 Bytes codiert werden können. Nicht alle Bytefolgen bilden in UTF-8 gültige Zeichen. Jedes Nicht-ASCII-Zeichen in UTF-8 beginnt mit einem Byte, in dem die zwei höchsten Bits gesetzt sind, und gibt an, wie viele Bytes mit dem höchsten (aber nicht dem zweithöchsten) gesetzten Bit folgen.

/dev/urandomenthält einen zufälligen Strom von Bytes. trtranskribiert Zeichen, daher müssen diese Bytes als Zeichen dekodiert werden. Diese ASCII-Zeichen in Ihrem Bereich sind alle in UTF-8 für ein Zeichen codiert, müssen jedoch trnoch alle Zeichen decodieren. Es gibt zum Beispiel andere AMehrbyte -Codierungen, bei denen einige andere Zeichen als das 0x41-Byte (der Code für A) enthalten.

Da dieser zufällige Bytestrom zwangsläufig ungültige Sequenzen enthält (zum Beispiel ist ein 0x80-Byte für sich in UTF-8 ungültig, da ein Nicht-ASCII-Zeichen mit einem Byte beginnen muss, das größer als 0xc1 ist (0xc0 und 0xc1 befinden sich in keinem UTF- 8 Zeichen)), wird also in diesem trFall mit einem Fehler zurückgegeben.

Was Sie hier wünschen, ist, diesen Strom von Bytes als Zeichen in einer Kodierung zu betrachten, die ein Byte pro Zeichen hat. Unabhängig davon , welche Sie wählen , ist nicht wichtig , da alle diese Zeichen in Ihrem Bereich (unter der Annahme von AZ, Sie bedeutete ABCDEFGHIJKLMNOPQRSTUVWXYZ und nicht Dinge wie Ý, Ê) sind Teil des tragbaren Zeichensatz so das gleiche in allen charsets auf Ihrem System unterstützt codiert werden.

Dafür würden Sie die eingestellte LC_CTYPELokalisierung Variable , die derjenige ist, der die charset entscheidet verwendet wird und welche Dinge wie blank, alphaZeichenklassen enthalten. Für die Definition des AZ-Bereichs möchten Sie jedoch auch die LC_COLLATEVariable festlegen (diejenige, die über die Reihenfolge der Zeichenfolgen entscheidet).

Das Gebietsschema Caka POSIXgarantiert, dass Zeichen Einzelbytes sind, und AZ ist ABCDEFGHIJKLMNOPQRSTUVWXYZ. Du könntest es tun:

 LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

(hier das -ans ende verschieben, sonst )-+wäre das als bereich zu nehmen wie A-Z)

Beachten Sie jedoch, dass die LC_ALLVariable alle anderen LC_*und LANGVariablen überschreibt . Wenn LC_ALLalso bereits etwas anderes definiert ist, hat das oben Gesagte keine Auswirkung. Also können Sie stattdessen einfach Folgendes tun:

 LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

Dies wirkt sich auf andere Dinge wie die Sprache der Fehlermeldungen aus. Das Ändern von LC_CTYPE könnte jedoch bereits ein Problem für Fehlermeldungen gewesen sein (z. B. keine Möglichkeit, russische oder japanische Fehlermeldungen im Zeichensatz des Gebietsschemas C auszudrücken).

Stéphane Chazelas
quelle
0

Laut der Manpage wird / dev / random wahrscheinlich für Ihre Bedürfnisse ausreichen. Vielleicht hat Apple aufgehört, das / dev / urandom zu erstellen, weil es unnötig ist?

jsbillings
quelle
Ich habe auch nicht /dev/random.
Kirk Woll
MacOSX sollte sowohl / dev / random als auch / dev / urandom haben. Vielleicht enthält Apple diese speziellen Dateien nicht mehr? Oder ist es nur dort, wenn Sie XCode installieren?
Jsbillings
1
FWIW, beide Geräte sind auf meiner von Lion auf Mountain Lion aktualisierten Workstation vorhanden. Ich glaube, es war auch auf Lion präsent. Die Knoten unterscheiden sich ebenfalls (13,0 vs. 13,1)
mrb