PEP 247 – API für kryptografische Hash-Funktionen
- Autor:
- A.M. Kuchling <amk at amk.ca>
- Status:
- Final
- Typ:
- Informational
- Erstellt:
- 23. Mär 2001
- Post-History:
- 20. Sep 2001
Inhaltsverzeichnis
Zusammenfassung
Es gibt mehrere verschiedene Module, die kryptografische Hashing-Algorithmen wie MD5 oder SHA implementieren. Dieses Dokument spezifiziert eine Standard-API für solche Algorithmen, um den Wechsel zwischen verschiedenen Implementierungen zu erleichtern.
Spezifikation
Alle Hashing-Module sollten die gleiche Schnittstelle aufweisen. Zusätzliche Methoden oder Variablen können hinzugefügt werden, aber die in diesem Dokument beschriebenen sollten immer vorhanden sein.
Hashfunktionsmodule definieren eine Funktion
new([string]) (nicht-verschlüsselte Hashes)new([key] , [string]) (verschlüsselte Hashes)Erzeugt ein neues Hashing-Objekt und gibt es zurück. Die erste Form ist für Hashes, die nicht verschlüsselt sind, wie MD5 oder SHA. Für verschlüsselte Hashes wie HMAC ist key ein erforderlicher Parameter, der einen String mit dem zu verwendenden Schlüssel enthält. In beiden Fällen wird der optionale string-Parameter, falls vorhanden, sofort in den Anfangszustand des Objekts gehasht, als obobj.update(string)aufgerufen worden wäre.Nachdem ein Hashing-Objekt erstellt wurde, können beliebige Strings über die
update()-Methode in das Objekt eingegeben werden, und der Hashwert kann jederzeit durch Aufrufen derdigest()-Methode des Objekts abgerufen werden.Beliebige zusätzliche Schlüsselwortargumente können zu dieser Funktion hinzugefügt werden, aber wenn sie nicht angegeben werden, sollten sinnvolle Standardwerte verwendet werden. Beispielsweise könnten die Schlüsselwörter
roundsunddigest_sizefür eine Hashfunktion hinzugefügt werden, die eine variable Anzahl von Runden und mehrere verschiedene Ausgabegrößen unterstützt, und sie sollten standardmäßig auf Werte gesetzt werden, die als sicher gelten.
Hashfunktionsmodule definieren eine Variable
digest_sizeEin ganzzahliger Wert; die Größe des vom Hashing-Objekt dieses Moduls erzeugten Digests, gemessen in Bytes. Sie könnten diesen Wert auch erhalten, indem Sie ein Beispielobjekt erstellen und auf dessendigest_size-Attribut zugreifen, aber es kann praktisch sein, diesen Wert vom Modul aus verfügbar zu haben. Hashes mit variabler Ausgabegröße setzen diese Variable aufNone.
Hashing-Objekte erfordern ein einzelnes Attribut
digest_sizeDieses Attribut ist identisch mit der Modul-weiten Variablendigest_sizeund misst die Größe des vom Hashing-Objekt erzeugten Digests, gemessen in Bytes. Wenn der Hash eine variable Ausgabegröße hat, muss diese Ausgabegröße bei der Erstellung des Hashing-Objekts gewählt werden, und dieses Attribut muss die gewählte Größe enthalten. Daher istNonekein gültiger Wert für dieses Attribut.
Hashing-Objekte erfordern die folgenden Methoden
copy()Gibt eine separate Kopie dieses Hashing-Objekts zurück. Eine Aktualisierung dieser Kopie beeinflusst das ursprüngliche Objekt nicht.
digest()Gibt den Hashwert dieses Hashing-Objekts als String mit 8-Bit-Daten zurück. Das Objekt wird durch diese Funktion in keiner Weise verändert; Sie können das Objekt nach dem Aufruf dieser Funktion weiter aktualisieren.
hexdigest()Gibt den Hashwert dieses Hashing-Objekts als String mit hexadezimalen Ziffern zurück. Kleinbuchstaben sollten für die Ziffernabisfverwendet werden. Wie die Methode.digest()darf auch diese Methode das Objekt nicht verändern.
update(string)Hasht den string in den aktuellen Zustand des Hashing-Objekts.update()kann während der Lebensdauer eines Hashing-Objekts beliebig oft aufgerufen werden.
Hashing-Module können zusätzliche Modul-weite Funktionen oder Objektmethoden definieren und trotzdem mit dieser Spezifikation konform sein.
Hier ist ein Beispiel mit einem Modul namens MD5
>>> from Crypto.Hash import MD5
>>> m = MD5.new()
>>> m.digest_size
16
>>> m.update('abc')
>>> m.digest()
'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'
>>> m.hexdigest()
'900150983cd24fb0d6963f7d28e17f72'
>>> MD5.new('abc').digest()
'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'
Begründung
Die Digest-Größe wird in Bytes und nicht in Bits gemessen, obwohl Hash-Algorithmus-Größen üblicherweise in Bits angegeben werden; MD5 ist beispielsweise ein 128-Bit-Algorithmus und nicht einer mit 16 Bytes. Dies liegt daran, dass in dem von mir untersuchten Beispielcode die Länge in Bytes oft benötigt wird (um in einer Datei vor- oder zurückzuspringen; um die Länge einer Ausgabesequenz zu berechnen), während die Länge in Bits selten verwendet wird. Daher fällt die Last auf die wenigen Leute, die die Größe in Bits tatsächlich benötigen, und diese müssen digest_size mit 8 multiplizieren.
Es wurde vorgeschlagen, die Methode update() besser append() zu nennen. Diese Methode bewirkt jedoch wirklich, dass der aktuelle Zustand des Hashing-Objekts aktualisiert wird, und update() wird bereits von den in Python enthaltenen Modulen md5 und sha verwendet, daher scheint es am einfachsten, den Namen update() beizubehalten.
Die Reihenfolge der Konstruktorargumente für verschlüsselte Hashes war ein heikles Thema. Es war nicht klar, ob der key an erster oder zweiter Stelle stehen sollte. Es handelt sich um einen erforderlichen Parameter, und die übliche Konvention ist, erforderliche Parameter zuerst zu platzieren, aber das bedeutet auch, dass der string-Parameter von der ersten an die zweite Position rückt. Es wäre möglich, sich zu verwirren und ein einzelnes Argument an einen verschlüsselten Hash zu übergeben, in der Annahme, dass man einen anfänglichen String an einen nicht-verschlüsselten Hash übergibt, aber es scheint nicht lohnenswert, die Schnittstelle für verschlüsselte Hashes komplizierter zu machen, um diesen potenziellen Fehler zu vermeiden.
Änderungen
17.09.2001: clear() in reset() umbenannt; digest_size-Attribut zu Objekten hinzugefügt; .hexdigest()-Methode hinzugefügt.
20.09.2001: reset()-Methode vollständig entfernt.
28.09.2001: digest_size für variable Größen-Hashes auf None gesetzt.
Danksagungen
Vielen Dank an Aahz, Andrew Archibald, Rich Salz, Itamar Shtull-Trauring und die Leser der python-crypto-Liste für ihre Kommentare zu diesem PEP.
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0247.rst
Zuletzt geändert: 2025-02-01 08:59:27 GMT