Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 452 – API für kryptografische Hash-Funktionen v2.0

Autor:
A.M. Kuchling <amk at amk.ca>, Christian Heimes <christian at python.org>
Status:
Final
Typ:
Informational
Erstellt:
15-Aug-2013
Post-History:

Ersetzt:
247

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 bereitstellen. 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])            (unge-schlüsselte Hashes)

new(key, [string], [digestmod])    (ge-schlüsselte Hashes)
Erstellt ein neues Hashing-Objekt und gibt es zurück. Die erste Form ist für unge-schlüsselte Hashes wie MD5 oder SHA. Für ge-schlü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 Parameter 'string', falls vorhanden, sofort in den Anfangszustand des Objekts gehasht, als ob obj.update(string) aufgerufen worden wäre.

Nachdem ein Hashing-Objekt erstellt wurde, können beliebige Bytes über seine update()-Methode in das Objekt eingegeben werden, und der Hash-Wert kann jederzeit durch Aufrufen der digest()-Methode des Objekts abgerufen werden.

Obwohl der Parameter 'string' genannt wird, arbeiten Hashing-Objekte nur mit 8-Bit-Daten. Sowohl 'key' als auch 'string' müssen ein bytes-ähnliches Objekt (bytes, bytearray...) sein. Ein Hashing-Objekt kann auch ein-dimensionale, zusammenhängende Puffer als Argument unterstützen. Text (Unicode) wird in Python 3.x nicht mehr unterstützt. Implementierungen für Python 2.x können Unicode ausschließlich mit ASCII-Zeichen als Argument annehmen, aber portabler Code sollte sich nicht auf diese Funktion verlassen.

Beliebige zusätzliche Schlüsselwortargumente können dieser Funktion hinzugefügt werden, aber wenn sie nicht angegeben werden, sollten sinnvolle Standardwerte verwendet werden. Zum Beispiel könnten die Schlüsselwörter 'rounds' und 'digest_size' für eine Hash-Funktion hinzugefügt werden, die eine variable Anzahl von Runden und mehrere verschiedene Ausgabegrößen unterstützt, und sie sollten Standardwerte haben, die als sicher gelten.

Hashfunktionsmodule definieren eine Variable

digest_size
Ein Integer-Wert; die Größe des von den Hashing-Objekten dieses Moduls erzeugten Digests, gemessen in Bytes. Sie könnten diesen Wert auch erhalten, indem Sie ein Beispielobjekt erstellen und auf sein 'digest_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 auf None.

Hashing-Objekte erfordern das folgende Attribut

digest_size
Dieses Attribut ist identisch mit der Modul-weiten Variable digest_size und gibt die Größe des von dem Hashing-Objekt erzeugten Digests in Bytes an. Wenn der Hash eine variable Ausgabegröße hat, muss diese Größe bei der Erstellung des Hashing-Objekts gewählt werden, und dieses Attribut muss die ausgewählte Größe enthalten. Daher ist None kein zulässiger Wert für dieses Attribut.
block_size
Ein Integer-Wert oder NotImplemented; die interne Blockgröße des Hash-Algorithmus in Bytes. Die Blockgröße wird vom HMAC-Modul verwendet, um den geheimen Schlüssel auf digest_size aufzufüllen oder um den geheimen Schlüssel zu hashen, wenn er länger als digest_size ist. Wenn kein HMAC-Algorithmus für den Hash-Algorithmus standardisiert ist, geben Sie stattdessen NotImplemented zurück.
name
Ein Textstring-Wert; der kanonische, kleingeschriebene Name des Hashing-Algorithmus. Der Name sollte ein geeigneter Parameter für hashlib.new sein.

Hashing-Objekte erfordern die folgenden Methoden

copy()
Gibt eine separate Kopie dieses Hashing-Objekts zurück. Ein Update dieser Kopie beeinflusst das ursprüngliche Objekt nicht.
digest()
Gibt den Hash-Wert dieses Hashing-Objekts als Bytes 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 Hash-Wert dieses Hashing-Objekts als String mit hexadezimalen Ziffern zurück. Kleinbuchstaben sollten für die Ziffern 'a' bis 'f' verwendet werden. Wie die Methode .digest() darf auch diese Methode das Objekt nicht verändern.
update(string)
Hasht den bytes-ähnlichen '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'

>>> import hashlib
>>> from Crypto.Hash import MD5
>>> m = MD5.new()
>>> isinstance(m, hashlib.CryptoHash)
True
>>> m.name
'md5'
>>> m.digest_size
16
>>> m.block_size
64
>>> m.update(b'abc')
>>> m.digest()
b'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'
>>> m.hexdigest()
'900150983cd24fb0d6963f7d28e17f72'
>>> MD5.new(b'abc').digest()
b'\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 normalerweise in Bits angegeben werden; MD5 ist beispielsweise ein 128-Bit-Algorithmus und kein 16-Byte-Algorithmus. 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ückzuspulen, um die Länge eines Ausgabestrings 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 die digest_size mit 8 multiplizieren müssen.

Es wurde vorgeschlagen, dass die Methode update() besser append() heißen sollte. Diese Methode verursacht jedoch tatsächlich, dass der aktuelle Zustand des Hashing-Objekts aktualisiert wird, und update() wird bereits von den in Python enthaltenen md5- und sha-Modulen verwendet, daher scheint es am einfachsten, den Namen update() beizubehalten.

Die Reihenfolge der Konstruktorargumente für ge-schlüsselte Hashes war ein strittiges Thema. Es war unklar, ob der Schlüssel zuerst oder als zweites kommen sollte. Es ist ein erforderlicher Parameter, und die übliche Konvention ist, erforderliche Parameter zuerst zu platzieren, aber das bedeutet auch, dass der Parameter 'string' von der ersten Position zur zweiten wandert. Es wäre möglich, sich zu irren und ein einzelnes Argument an einen ge-schlüsselten Hash zu übergeben und zu denken, dass man einen initialen String an einen unge-schlüsselten Hash übergibt, aber es scheint nicht wert zu sein, die Schnittstelle für ge-schlüsselte Hashes obskurer zu gestalten, um diesen potenziellen Fehler zu vermeiden.

Änderungen von Version 1.0 zu Version 2.0

Version 2.0 der API für kryptografische Hash-Funktionen klärt einige Aspekte der API und bringt sie auf den neuesten Stand. Sie formalisierte auch Aspekte, die bereits de facto Standards waren und von den meisten Implementierungen bereitgestellt wurden.

Version 2.0 führt die folgenden neuen Attribute ein

name
Die 'name'-Eigenschaft wurde durch Issue 18532 obligatorisch gemacht.
block_size
Die neue Version gibt auch an, dass der Rückgabewert NotImplemented die HMAC-Unterstützung verhindert.

Version 2.0 berücksichtigt die Trennung von binären und Textdaten in Python 3.0. Das Argument 'string' für new() und update() sowie das Argument 'key' müssen bytes-ähnliche Objekte sein. Unter Python 2.x kann ein Hashing-Objekt auch Unicode ausschließlich mit ASCII-Zeichen unterstützen. Der tatsächliche Name des Arguments wird nicht geändert, da er Teil der öffentlichen API ist. Code kann davon abhängen, dass das Argument 'string' heißt.

Ä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 Hashes mit variabler Größe auf None gesetzt.
  • 15.08.2013: block_size- und name-Attribute hinzugefügt; klargestellt, dass sich 'string' tatsächlich auf bytes-ähnliche Objekte bezieht.

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.


Quelle: https://github.com/python/peps/blob/main/peps/pep-0452.rst

Zuletzt geändert: 2025-02-01 08:59:27 GMT