hashlib — Säkra hashar och meddelandesammanställningar

Källkod: Lib/hashlib.py


Denna modul implementerar ett gemensamt gränssnitt för många olika hashalgoritmer. Här ingår de säkra FIPS-hashalgoritmerna SHA224, SHA256, SHA384, SHA512, (definierade i the FIPS 180-4 standard), SHA-3-serien (definierad i the FIPS 202 standard) samt de äldre algoritmerna SHA1 (formerly part of FIPS) och MD5-algoritmen (definierad i internet RFC 1321).

Anteckning

Om du vill ha hashfunktionerna adler32 eller crc32 finns de tillgängliga i modulen zlib.

Hash-algoritmer

Det finns en konstruktörsmetod för varje typ av hash. Alla returnerar ett hash-objekt med samma enkla gränssnitt. Till exempel: använd sha256() för att skapa ett SHA-256 hash-objekt. Du kan nu mata detta objekt med bytes-liknande objekt (normalt bytes) med hjälp av metoden update. När som helst kan du be den om digest av sammankopplingen av de data som hittills matats till den med hjälp av metoderna digest() eller hexdigest().

För att möjliggöra multithreading släpps Python GIL när en hash beräknas som levererar mer än 2047 byte data samtidigt i sin konstruktor eller .update-metod.

Konstruktörer för hashalgoritmer som alltid finns i denna modul är sha1(), sha224(), sha256(), sha384(), sha512(), sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256(), blake2b(), och blake2s(). md5() är normalt också tillgänglig, men den kan saknas eller vara blockerad om du använder en sällsynt ”FIPS-kompatibel” version av Python. Dessa motsvarar algorithms_guaranteed.

Ytterligare algoritmer kan också vara tillgängliga om din Python-distributions hashlib länkades mot en version av OpenSSL som tillhandahåller andra. Andra är inte garanterat tillgängliga på alla installationer och kommer endast att vara tillgängliga med namn via new(). Se algorithms_available.

Varning

Vissa algoritmer har kända svagheter när det gäller hashkollisioner (bland annat MD5 och SHA1). Se Attacker mot kryptografiska hashalgoritmer och avsnittet hashlib-seealso i slutet av det här dokumentet.

Tillagd i version 3.6: SHA3 (Keccak) och SHAKE-konstruktörerna sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256() lades till. blake2b() och blake2s() lades till.

Ändrad i version 3.9: Alla hashlib-konstruktörer tar ett nyckelordsargument usedforsecurity med standardvärdet True. Ett falskt värde gör det möjligt att använda osäkra och blockerade hashalgoritmer i begränsade miljöer. False anger att hashingalgoritmen inte används i säkerhetssammanhang, t.ex. som en icke-kryptografisk envägskomprimeringsfunktion.

Ändrad i version 3.9: Hashlib använder nu SHA3 och SHAKE från OpenSSL om det finns tillgängligt.

Ändrad i version 3.12: För någon av algoritmerna MD5, SHA1, SHA2 eller SHA3 som den länkade OpenSSL inte tillhandahåller faller vi tillbaka på en verifierad implementering från HACL*-projektet.

Användning

För att erhålla digest av bytesträngen b"Ingen inspekterar den spammiga upprepningen":

>>> import hashlib
>>> m = hashlib.sha256()
>>> m.update(b"Nobody inspects")
>>> m.update(b" the spammish repetition")
>>> m.digest()
b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06'
>>> m.hexdigest()
'031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

Mer komprimerad:

>>> hashlib.sha256(b"Nobody inspects the spammish repetition").hexdigest()
'031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

Konstruktörer

hashlib.new(name, [data, ]*, usedforsecurity=True)

Är en generisk konstruktör som tar strängen namn för den önskade algoritmen som sin första parameter. Den finns också för att ge tillgång till de ovan listade hasharna samt alla andra algoritmer som ditt OpenSSL-bibliotek kan erbjuda.

Använda new() med ett algoritmnamn:

>>> h = hashlib.new('sha256')
>>> h.update(b"Nobody inspects the spammish repetition")
>>> h.hexdigest()
'031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'
hashlib.md5([data, ]*, usedforsecurity=True)
hashlib.sha1([data, ]*, usedforsecurity=True)
hashlib.sha224([data, ]*, usedforsecurity=True)
hashlib.sha256([data, ]*, usedforsecurity=True)
hashlib.sha384([data, ]*, usedforsecurity=True)
hashlib.sha512([data, ]*, usedforsecurity=True)
hashlib.sha3_224([data, ]*, usedforsecurity=True)
hashlib.sha3_256([data, ]*, usedforsecurity=True)
hashlib.sha3_384([data, ]*, usedforsecurity=True)
hashlib.sha3_512([data, ]*, usedforsecurity=True)

Namngivna konstruktörer som dessa är snabbare än att skicka ett algoritmnamn till new().

Attribut

Hashlib tillhandahåller följande attribut för konstanta moduler:

hashlib.algorithms_guaranteed

En uppsättning som innehåller namnen på de hashalgoritmer som garanterat stöds av denna modul på alla plattformar. Observera att ’md5’ finns med i denna lista trots att vissa uppströmsleverantörer erbjuder en udda ”FIPS-kompatibel” Python-byggnad som utesluter den.

Tillagd i version 3.2.

hashlib.algorithms_available

En uppsättning som innehåller namnen på de hashalgoritmer som är tillgängliga i den Python-tolk som körs. Dessa namn kommer att kännas igen när de skickas till new(). algorithms_guaranteed kommer alltid att vara en delmängd. Samma algoritm kan förekomma flera gånger i denna uppsättning under olika namn (tack vare OpenSSL).

Tillagd i version 3.2.

Hash-objekt

Följande värden tillhandahålls som konstanta attribut för de hash-objekt som returneras av konstruktörerna:

hash.digest_size

Storleken på den resulterande hashen i bytes.

hash.block_size

Den interna blockstorleken för hashalgoritmen i bytes.

Ett hash-objekt har följande attribut:

hash.name

Det kanoniska namnet på denna hash, alltid gemener och alltid lämpligt som parameter till new() för att skapa en annan hash av denna typ.

Ändrad i version 3.4: Namnattributet har funnits i CPython sedan starten, men fram till Python 3.4 var det inte formellt specificerat, så det kanske inte finns på vissa plattformar.

Ett hash-objekt har följande metoder:

hash.update(data)

Uppdaterar hash-objektet med bytesliknande objekt. Upprepade anrop är likvärdiga med ett enda anrop med en sammankoppling av alla argument: m.update(a); m.update(b) är likvärdigt med m.update(a+b).

hash.digest()

Returnerar sammanfattningen av de data som hittills skickats till update()-metoden. Detta är ett bytesobjekt av storleken digest_size som kan innehålla bytes i hela intervallet 0 till 255.

hash.hexdigest()

Som digest() förutom att digestet returneras som ett strängobjekt med dubbel längd, som endast innehåller hexadecimala siffror. Detta kan användas för att utbyta värdet på ett säkert sätt i e-post eller andra icke-binära miljöer.

hash.copy()

Returnerar en kopia (”klon”) av hash-objektet. Detta kan användas för att effektivt beräkna digests av data som delar en gemensam initial substring.

SHAKE-digitaliseringar med variabel längd

hashlib.shake_128([data, ]*, usedforsecurity=True)
hashlib.shake_256([data, ]*, usedforsecurity=True)

Algoritmerna shake_128() och shake_256() ger digests av varierande längd med length_in_bits//2 upp till 128 eller 256 bitars säkerhet. Därför kräver deras digest-metoder en längd. Den maximala längden begränsas inte av SHAKE-algoritmen.

shake.digest(length)

Returnerar sammanfattningen av de data som hittills skickats till metoden update(). Detta är ett bytesobjekt av storleken length som kan innehålla bytes i hela intervallet från 0 till 255.

shake.hexdigest(length)

Som digest() förutom att digestet returneras som ett strängobjekt med dubbel längd, som endast innehåller hexadecimala siffror. Detta kan användas för att utbyta värdet i e-post eller andra icke-binära miljöer.

Exempel på användning:

>>> h = hashlib.shake_256(b'Nobody inspects the spammish repetition')
>>> h.hexdigest(20)
'44709d6fcb83d92a76dcb0b668c98e1b1d3dafe7'

Hashning av filer

Modulen hashlib tillhandahåller en hjälpfunktion för effektiv hashing av en fil eller ett filliknande objekt.

hashlib.file_digest(fileobj, digest, /)

Returnerar ett digest-objekt som har uppdaterats med innehållet i filobjektet.

fileobj måste vara ett filliknande objekt som öppnas för läsning i binärt läge. Den accepterar filobjekt från inbyggda open(), BytesIO-instanser, SocketIO-objekt från socket.socket.makefile() och liknande. fileobj måste öppnas i blockeringsläge, annars kan ett BlockingIOError uppstå.

Funktionen kan förbigå Pythons I/O och använda filbeskrivaren från fileno() direkt. fileobj måste antas vara i ett okänt tillstånd efter att denna funktion returneras eller höjs. Det är upp till den som anropar att stänga fileobj.

digest måste antingen vara ett namn på en hashalgoritm som en str, en hashkonstruktör eller en callable som returnerar ett hashobjekt.

Exempel:

>>> import io, hashlib, hmac
>>> with open("library/hashlib.rst", "rb") as f:
...     digest = hashlib.file_digest(f, "sha256")
...
>>> digest.hexdigest()
'...'
>>> buf = io.BytesIO(b"somedata")
>>> mac1 = hmac.HMAC(b"key", digestmod=hashlib.sha512)
>>> digest = hashlib.file_digest(buf, lambda: mac1)
>>> digest is mac1
True
>>> mac2 = hmac.HMAC(b"key", b"somedata", digestmod=hashlib.sha512)
>>> mac1.digest() == mac2.digest()
True

Tillagd i version 3.11.

Ändrad i version 3.14: Ger nu upphov till ett BlockingIOError om filen öppnas i blockeringsläge. Tidigare lades falska nollbytes till i sammanfattningen.

Härledning av nycklar

Algoritmer för nyckelderivation och nyckelsträckning är utformade för säker hashing av lösenord. Naiva algoritmer som sha1(lösenord) är inte motståndskraftiga mot brute-force-attacker. En bra hashfunktion för lösenord måste vara inställbar, långsam och innehålla en salt.

hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)

Funktionen tillhandahåller PKCS#5 lösenordsbaserad nyckelavledningsfunktion 2. Den använder HMAC som pseudorandomfunktion.

Strängen hash_name är det önskade namnet på hashdigestalgoritmen för HMAC, t.ex. ”sha1” eller ”sha256”. password och salt tolkas som buffertar av bytes. Program och bibliotek bör begränsa password till en vettig längd (t.ex. 1024). salt bör vara cirka 16 eller fler byte från en lämplig källa, t.ex. os.urandom().

Antalet iterationer bör väljas baserat på hashalgoritmen och datorkraften. Från och med 2022 föreslås hundratusentals iterationer av SHA-256. För motivering till varför och hur man väljer vad som är bäst för din applikation, läs Appendix A.2.2 i NIST-SP-800-132. Svaren på stackexchange pbkdf2 iterations question förklarar i detalj.

dklen är längden på den härledda nyckeln i byte. Om dklen är None används digeststorleken för hashalgoritmen hash_name, t.ex. 64 för SHA-512.

>>> from hashlib import pbkdf2_hmac
>>> our_app_iters = 500_000  # Application specific, read above.
>>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt' * 2, our_app_iters)
>>> dk.hex()
'15530bba69924174860db778f2c6f8104d3aaf9d26241840c8c4a641c8d000a9'

Funktionen är endast tillgänglig när Python är kompilerad med OpenSSL.

Tillagd i version 3.4.

Ändrad i version 3.12: Funktionen är nu endast tillgänglig när Python är byggt med OpenSSL. Den långsamma rena Python-implementationen har tagits bort.

hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)

Funktionen tillhandahåller en lösenordsbaserad nyckelavledningsfunktion för scrypt enligt definitionen i RFC 7914.

password och salt måste vara bytesliknande objekt. Program och bibliotek bör begränsa password till en rimlig längd (t.ex. 1024). salt bör vara cirka 16 eller fler byte från en lämplig källa, t.ex. os.urandom().

n är kostnadsfaktorn för CPU/minne, r blockstorleken, p parallelliseringsfaktorn och maxmem begränsar minnet (OpenSSL 1.1.0 är 32 MiB som standard). dklen är längden på den härledda nyckeln i byte.

Tillagd i version 3.6.

BLAKE2

BLAKE2 är en kryptografisk hashfunktion som definieras i RFC 7693 och finns i två varianter:

  • BLAKE2b, optimerad för 64-bitars plattformar och producerar digests i alla storlekar mellan 1 och 64 byte,

  • BLAKE2s, optimerad för 8- till 32-bitars plattformar och producerar digests i alla storlekar mellan 1 och 32 byte.

BLAKE2 stöder keyed mode (en snabbare och enklare ersättning för HMAC), salted hashing, personalization och tree hashing.

Hash-objekt från den här modulen följer API:et för standardbibliotekets hashlib-objekt.

Skapa hash-objekt

Nya hash-objekt skapas genom att anropa konstruktörsfunktioner:

hashlib.blake2b(data=b'', *, digest_size=64, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)
hashlib.blake2s(data=b'', *, digest_size=32, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)

Dessa funktioner returnerar motsvarande hash-objekt för beräkning av BLAKE2b eller BLAKE2s. De tar valfritt dessa allmänna parametrar:

  • data: den första delen av data som ska hashas, som måste vara bytesliknande objekt. Det kan endast skickas som ett positionellt argument.

  • digest_size: storlek på utmatad digest i byte.

  • key: nyckel för hashing med nyckel (upp till 64 byte för BLAKE2b, upp till 32 byte för BLAKE2s).

  • salt: salt för randomiserad hashing (upp till 16 byte för BLAKE2b, upp till 8 byte för BLAKE2s).

  • person: personaliseringssträng (upp till 16 byte för BLAKE2b, upp till 8 byte för BLAKE2s).

I följande tabell visas gränser för allmänna parametrar (i byte):

Hash

digest_size

len(key)

len(salt)

len(person)

BLAKE2b

64

64

16

16

BLAKE2s

32

32

8

8

Anteckning

BLAKE2-specifikationen definierar konstanta längder för salt- och personaliseringsparametrar, men för enkelhetens skull accepterar den här implementationen bytesträngar av valfri storlek upp till den angivna längden. Om parameterns längd är mindre än den angivna fylls den på med nollor, vilket innebär att till exempel b'salt' och b'salt\x00' är samma värde. (Detta är inte fallet för key.)

Dessa storlekar finns tillgängliga som modul konstanter som beskrivs nedan.

Konstruktörsfunktionerna accepterar även följande parametrar för trädhashning:

  • fanout: fanout (0 till 255, 0 om obegränsad, 1 i sekventiellt läge).

  • depth: trädets maximala djup (1 till 255, 255 om det är obegränsat, 1 i sekventiellt läge).

  • leaf_size: maximal byte-längd för bladet (0 till 2**32-1, 0 om obegränsat eller i sekventiellt läge).

  • node_offset: nodoffset (0 till 2**64-1 för BLAKE2b, 0 till 2**48-1 för BLAKE2s, 0 för den första, längst till vänster, blad eller i sekventiellt läge).

  • node_depth: noddjup (0 till 255, 0 för blad eller i sekventiellt läge).

  • inner_size: inner digest size (0 till 64 för BLAKE2b, 0 till 32 för BLAKE2s, 0 i sekventiellt läge).

  • last_node: boolean som anger om den bearbetade noden är den sista (False för sekventiellt läge).

Förklaring av parametrar för trädläge.

Se avsnitt 2.10 i BLAKE2-specifikationen för en omfattande genomgång av trädhashing.

Konstanter

blake2b.SALT_SIZE
blake2s.SALT_SIZE

Saltlängd (maximal längd som accepteras av konstruktörer).

blake2b.PERSON_SIZE
blake2s.PERSON_SIZE

Längd på personaliseringssträngen (maximal längd som accepteras av konstruktörerna).

blake2b.MAX_KEY_SIZE
blake2s.MAX_KEY_SIZE

Maximal nyckelstorlek.

blake2b.MAX_DIGEST_SIZE
blake2s.MAX_DIGEST_SIZE

Maximal digest-storlek som hashfunktionen kan mata ut.

Exempel

Enkel hashing

För att beräkna hash för vissa data bör du först konstruera ett hashobjekt genom att anropa lämplig konstruktörsfunktion (blake2b() eller blake2s()), sedan uppdatera det med data genom att anropa update() på objektet och slutligen få ut digest från objektet genom att anropa digest() (eller hexdigest() för hex-kodad sträng).

>>> from hashlib import blake2b
>>> h = blake2b()
>>> h.update(b'Hello world')
>>> h.hexdigest()
'6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

Som en genväg kan du skicka den första delen av data som ska uppdateras direkt till konstruktören som positionsargument:

>>> from hashlib import blake2b
>>> blake2b(b'Hello world').hexdigest()
'6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

Du kan anropa hash.update() så många gånger som du behöver för att iterativt uppdatera hashen:

>>> from hashlib import blake2b
>>> items = [b'Hello', b' ', b'world']
>>> h = blake2b()
>>> for item in items:
...     h.update(item)
...
>>> h.hexdigest()
'6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

Använda olika digest-storlekar

BLAKE2 har konfigurerbar storlek på sammanställningar upp till 64 byte för BLAKE2b och upp till 32 byte för BLAKE2s. Om vi till exempel vill ersätta SHA-1 med BLAKE2b utan att ändra storleken på utdata kan vi säga till BLAKE2b att producera 20-byte-sammanställningar:

>>> from hashlib import blake2b
>>> h = blake2b(digest_size=20)
>>> h.update(b'Replacing SHA1 with the more secure function')
>>> h.hexdigest()
'd24f26cf8de66472d58d4e1b1774b4c9158b1f4c'
>>> h.digest_size
20
>>> len(h.digest())
20

Hashobjekt med olika digeststorlekar har helt olika utdata (kortare hash är inte prefix av längre hash); BLAKE2b och BLAKE2s ger olika utdata även om utdatalängden är densamma:

>>> from hashlib import blake2b, blake2s
>>> blake2b(digest_size=10).hexdigest()
'6fa1d8fcfd719046d762'
>>> blake2b(digest_size=11).hexdigest()
'eb6ec15daf9546254f0809'
>>> blake2s(digest_size=10).hexdigest()
'1bf21a98c78a1c376ae9'
>>> blake2s(digest_size=11).hexdigest()
'567004bf96e4a25773ebf4'

Hashtagning med nyckel

Keyed hashing kan användas för autentisering som en snabbare och enklare ersättning för Hash-based message authentication code (HMAC). BLAKE2 kan användas på ett säkert sätt i prefix-MAC-läge tack vare egenskapen indifferentiability som ärvs från BLAKE.

Detta exempel visar hur man får en (hex-kodad) 128-bitars autentiseringskod för meddelande b'meddelandedata' med nyckel b'pseudorandomnyckel':

>>> from hashlib import blake2b
>>> h = blake2b(key=b'pseudorandom key', digest_size=16)
>>> h.update(b'message data')
>>> h.hexdigest()
'3d363ff7401e02026f4a4687d4863ced'

Som ett praktiskt exempel kan en webbapplikation symmetriskt signera cookies som skickas till användare och senare verifiera dem för att säkerställa att de inte har manipulerats:

>>> from hashlib import blake2b
>>> from hmac import compare_digest
>>>
>>> SECRET_KEY = b'pseudorandomly generated server secret key'
>>> AUTH_SIZE = 16
>>>
>>> def sign(cookie):
...     h = blake2b(digest_size=AUTH_SIZE, key=SECRET_KEY)
...     h.update(cookie)
...     return h.hexdigest().encode('utf-8')
>>>
>>> def verify(cookie, sig):
...     good_sig = sign(cookie)
...     return compare_digest(good_sig, sig)
>>>
>>> cookie = b'user-alice'
>>> sig = sign(cookie)
>>> print("{0},{1}".format(cookie.decode('utf-8'), sig))
user-alice,b'43b3c982cf697e0c5ab22172d1ca7421'
>>> verify(cookie, sig)
True
>>> verify(b'user-bob', sig)
False
>>> verify(cookie, b'0102030405060708090a0b0c0d0e0f00')
False

Även om det finns ett inbyggt hashningsläge med nyckel kan BLAKE2 naturligtvis användas i HMAC-konstruktion med hmac module:

>>> import hmac, hashlib
>>> m = hmac.new(b'secret key', digestmod=hashlib.blake2s)
>>> m.update(b'message')
>>> m.hexdigest()
'e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142'

Slumpmässig hashing

Genom att ställa in parametern salt kan användare införa randomisering i hashfunktionen. Randomiserad hashfunktion är användbar för att skydda mot kollisionsattacker på den hashfunktion som används i digitala signaturer.

Slumpmässig hashfunktion är avsedd för situationer där en part, den som förbereder meddelandet, genererar hela eller delar av ett meddelande som ska signeras av en annan part, den som signerar meddelandet. Om den som förbereder meddelandet kan hitta kollisioner mellan kryptografiska hashfunktioner (dvs. två meddelanden som ger samma hashvärde) kan han eller hon förbereda meningsfulla versioner av meddelandet som ger samma hashvärde och digitala signatur, men med olika resultat (t.ex. överföring av 1 000 000 USD till ett konto i stället för 10 USD). Kryptografiska hashfunktioner har utformats med kollisionsmotstånd som ett huvudmål, men den nuvarande koncentrationen på att attackera kryptografiska hashfunktioner kan leda till att en viss kryptografisk hashfunktion ger mindre kollisionsmotstånd än förväntat. Slumpmässig hashning ger undertecknaren ytterligare skydd genom att minska sannolikheten för att en förberedare kan generera två eller flera meddelanden som i slutändan ger samma hashvärde under processen för generering av digitala signaturer — även om det är praktiskt att hitta kollisioner för hashfunktionen. Användningen av randomiserad hashning kan dock minska den säkerhet som en digital signatur ger när alla delar av meddelandet förbereds av undertecknaren.

(NIST SP-800-106 ”Randomized Hashing for Digital Signatures”)

I BLAKE2 behandlas saltet som en engångsingång till hashfunktionen under initialiseringen, i stället för som en ingång till varje komprimeringsfunktion.

Varning

Salted hashing (eller bara hashing) med BLAKE2 eller någon annan kryptografisk hashfunktion för allmänt bruk, t.ex. SHA-256, är inte lämplig för hashing av lösenord. Se BLAKE2 FAQ för mer information.

>>> import os
>>> from hashlib import blake2b
>>> msg = b'some message'
>>> # Calculate the first hash with a random salt.
>>> salt1 = os.urandom(blake2b.SALT_SIZE)
>>> h1 = blake2b(salt=salt1)
>>> h1.update(msg)
>>> # Calculate the second hash with a different random salt.
>>> salt2 = os.urandom(blake2b.SALT_SIZE)
>>> h2 = blake2b(salt=salt2)
>>> h2.update(msg)
>>> # The digests are different.
>>> h1.digest() != h2.digest()
True

Anpassning

Ibland är det användbart att tvinga hashfunktionen att producera olika sammanställningar för samma indata för olika ändamål. Citerar författarna till Skein-hashfunktionen:

Vi rekommenderar att alla applikationsdesigners allvarligt överväger att göra detta; vi har sett många protokoll där en hash som beräknas i en del av protokollet kan användas i en helt annan del eftersom två hashberäkningar gjordes på liknande eller relaterade data, och angriparen kan tvinga applikationen att göra hashingångarna desamma. Genom att anpassa varje hashfunktion som används i protokollet stoppas den här typen av angrepp.

(The Skein Hash Function Family, p. 21)

BLAKE2 kan anpassas genom att skicka bytes till person-argumentet:

>>> from hashlib import blake2b
>>> FILES_HASH_PERSON = b'MyApp Files Hash'
>>> BLOCK_HASH_PERSON = b'MyApp Block Hash'
>>> h = blake2b(digest_size=32, person=FILES_HASH_PERSON)
>>> h.update(b'the same content')
>>> h.hexdigest()
'20d9cd024d4fb086aae819a1432dd2466de12947831b75c5a30cf2676095d3b4'
>>> h = blake2b(digest_size=32, person=BLOCK_HASH_PERSON)
>>> h.update(b'the same content')
>>> h.hexdigest()
'cf68fb5761b9c44e7878bfb2c4c9aea52264a80b75005e65619778de59f383a3'

Personalisering tillsammans med keyed mode kan också användas för att härleda olika nycklar från en enda.

>>> from hashlib import blake2s
>>> from base64 import b64decode, b64encode
>>> orig_key = b64decode(b'Rm5EPJai72qcK3RGBpW3vPNfZy5OZothY+kHY6h21KM=')
>>> enc_key = blake2s(key=orig_key, person=b'kEncrypt').digest()
>>> mac_key = blake2s(key=orig_key, person=b'kMAC').digest()
>>> print(b64encode(enc_key).decode('utf-8'))
rbPb15S/Z9t+agffno5wuhB77VbRi6F9Iv2qIxU7WHw=
>>> print(b64encode(mac_key).decode('utf-8'))
G9GtHFE1YluXY1zWPlYk1e/nWfu0WSEb0KRcjhDeP/o=

Trädläge

Här är ett exempel på hashing av ett minimalt träd med två bladnoder:

  10
 /  \
00  01

I det här exemplet används 64-bytes interna sammanställningar och den slutliga sammanställningen på 32 byte returneras:

>>> from hashlib import blake2b
>>>
>>> FANOUT = 2
>>> DEPTH = 2
>>> LEAF_SIZE = 4096
>>> INNER_SIZE = 64
>>>
>>> buf = bytearray(6000)
>>>
>>> # Left leaf
... h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH,
...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
...               node_offset=0, node_depth=0, last_node=False)
>>> # Right leaf
... h01 = blake2b(buf[LEAF_SIZE:], fanout=FANOUT, depth=DEPTH,
...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
...               node_offset=1, node_depth=0, last_node=True)
>>> # Root node
... h10 = blake2b(digest_size=32, fanout=FANOUT, depth=DEPTH,
...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
...               node_offset=0, node_depth=1, last_node=True)
>>> h10.update(h00.digest())
>>> h10.update(h01.digest())
>>> h10.hexdigest()
'3ad2a9b37c6070e374c7a8c508fe20ca86b6ed54e286e93a0318e95e881db5aa'

Tack till

BLAKE2 designades av Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O’Hearn och Christian Winnerlein baserat på SHA-3-finalisten BLAKE skapad av Jean-Philippe Aumasson, Luca Henzen, Willi Meier och Raphael C.-W. Phan.

Den använder kärnalgoritmen från ChaCha-chiffer som designats av Daniel J. Bernstein.

Stdlib-implementeringen är baserad på modulen pyblake2. Den skrevs av Dmitry Chestnykh baserat på C-implementering skriven av Samuel Neves. Dokumentationen kopierades från pyblake2 och skrevs av Dmitry Chestnykh.

C-koden har delvis skrivits om för Python av Christian Heimes.

Följande public domain-dedikation gäller för både implementeringen av C-hashfunktionen, tilläggskoden och denna dokumentation:

I den utsträckning det är möjligt enligt lag har författaren/författarna tillägnat all upphovsrätt och alla närstående rättigheter till denna programvara till den offentliga domänen över hela världen. Denna programvara distribueras utan någon garanti.

Du bör ha fått en kopia av CC0 Public Domain Dedication tillsammans med den här programvaran. Om inte, se https://creativecommons.org/publicdomain/zero/1.0/.

Följande personer har hjälpt till med utvecklingen eller bidragit med sina ändringar till projektet och den offentliga domänen enligt Creative Commons Public Domain Dedication 1.0 Universal:

  • Alexandr Sokolovskiy

Se även

Modul hmac

En modul för att generera autentiseringskoder för meddelanden med hjälp av hash.

Modul base64

Ett annat sätt att koda binära hashar för icke-binära miljöer.

https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.180-4.pdf

FIPS 180-4-publikationen om säkra hashalgoritmer.

https://csrc.nist.gov/pubs/fips/202/final

FIPS 202-publikationen om SHA-3-standarden.

https://www.blake2.net/

Officiell webbplats för BLAKE2.

https://en.wikipedia.org/wiki/Cryptographic_hash_function

Wikipedia-artikel med information om vilka algoritmer som har kända problem och vad det innebär för användningen av dem.

https://www.ietf.org/rfc/rfc8018.txt

PKCS #5: Specifikation för lösenordsbaserad kryptografi version 2.1

https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf

NIST:s rekommendation för lösenordsbaserad nyckelavledning.