Perché Git usa una funzione hash crittografica?


139

Perché Git usa SHA-1 , una funzione hash crittografica, anziché una funzione hash non crittografica più veloce?

Domanda correlata:

Stack Overflow question Perché Git usa SHA-1 come numeri di versione? chiede perché Git usa SHA-1 invece di numeri sequenziali per i commit.


Personalmente penso che anche l'uso di SHA-1 rotto su SHA-2 sia stata un'ottimizzazione prematura.
Codici A Caos

7
@CodesInChaos: e inoltre, inserire un particolare algoritmo nel codice è stata un'orribile violazione dei principi DI. Dovrebbe essere in un file di configurazione XML da qualche parte ;-)
Steve Jessop

Aggiornamento dicembre 2017 con Git 2.16 (Q1 2018): è in corso uno sforzo per supportare un SHA alternativo: vedi " Perché Git non utilizza un SHA più moderno? ".
VonC,

Non ci sono buone a 160 bit o superiore hash non crittografiche. La maggior parte sono funzioni a 32, 64 o 128 bit altamente ottimizzate. 128 bit va bene, ma ho la sensazione che 128 bit sia un po 'basso per un grande progetto come Git. Se uscisse un hash veloce e di alta qualità a 224/256 bit, sarebbe probabilmente l'ideale.
bryc,

Risposte:


197

TLDR;


Puoi verificarlo dallo stesso Linus Torvalds, quando ha presentato Git a Google nel 2007 :
(enfasi sul mio)

Controlliamo i checksum considerati crittograficamente sicuri. Nessuno è stato in grado di interrompere SHA-1, ma il punto è che SHA-1 per quanto riguarda git, non è nemmeno una funzionalità di sicurezza. È puramente un controllo di coerenza .
Le parti di sicurezza sono altrove. Molte persone credono che, poiché git usa SHA-1 e SHA-1 è usato per cose crittograficamente sicure, pensano che sia un'enorme funzionalità di sicurezza. Non ha nulla a che fare con la sicurezza, è solo il miglior hash che puoi ottenere.

Avere un buon hash è buono per essere in grado di fidarsi dei tuoi dati , capita anche di avere altre buone caratteristiche, significa che quando abbiamo hash oggetti, sappiamo che l'hash è ben distribuito e non dobbiamo preoccuparci di alcuni problemi di distribuzione .

Internamente significa dal punto di vista dell'implementazione, possiamo fidarci che l'hash è così buono che possiamo usare algoritmi di hashing e sapere che non ci sono casi negativi.

Quindi ci sono alcuni motivi per apprezzare anche il lato crittografico, ma riguarda davvero la capacità di fidarsi dei tuoi dati.
Ti garantisco, se metti i tuoi dati in git, puoi fidarti del fatto che cinque anni dopo, dopo che sono stati convertiti dal tuo disco rigido in DVD in qualsiasi nuova tecnologia e dopo averli copiati, cinque anni dopo puoi verificare i dati che hai tornare indietro è esattamente gli stessi dati che hai inserito. E questo è qualcosa che dovresti davvero cercare in un sistema di gestione del codice sorgente .


Aggiornamento dicembre 2017 con Git 2.16 (Q1 2018): è in corso questo sforzo per supportare un SHA alternativo: vedi " Perché Git non utilizza un SHA più moderno? ".


Ho citato in " Come sarebbe GIT gestire una collisione SHA1 su un blob? " Che si potrebbe progettare un commit con una particolare SHA1 prefisso (ancora uno sforzo estremamente costoso).
Ma il punto rimane, come cita Eric Sink nel libro " Git: Cryptographic Hash " ( Version Control by Example (2011) :

È piuttosto importante che il DVCS non incontri mai due diversi pezzi di dati che abbiano lo stesso digest. Fortunatamente, le buone funzioni di hash crittografico sono progettate per rendere estremamente improbabili tali collisioni.

È più difficile trovare un buon hash non crittografico con un basso tasso di collisione, a meno che non si consideri la ricerca come " Trovare hash non crittografici all'avanguardia con la programmazione genetica ".

Puoi anche leggere " Prendi in considerazione l'uso di un algoritmo di hash non crittografico per accelerare l'hash ", che menziona ad esempio " xxhash ", un algoritmo Hash non crittografico estremamente veloce, che lavora a velocità vicine ai limiti di RAM.


Le discussioni su come cambiare l'hash in Git non sono nuove:

(Linus Torvalds)

Non c'è davvero nulla che rimane del codice mozilla, ma ehi, ho iniziato da esso. Con il senno di poi probabilmente avrei dovuto partire dal codice asm PPC che ha già fatto il blocco in modo corretto, ma è un tipo di cose "20/20 senno di poi".

Inoltre, il codice di Mozilla, essendo un mucchio orribile di rozzo, era il motivo per cui ero così convinto di poter migliorare le cose. Quindi è una specie di fonte, anche se riguarda più il lato motivazionale di qualsiasi altro codice rimanente;)

E devi stare attento a come misurare il guadagno di ottimizzazione effettivo

(Linus Torvalds)

Ti posso praticamente garantire che migliora le cose solo perché fa in modo che gcc generi codice merda, che poi nasconde alcuni dei problemi di P4.

(John Tapsell - johnflux)

Il costo di ingegneria per l'aggiornamento di git da SHA-1 a un nuovo algoritmo è molto più elevato . Non sono sicuro di come si possa fare bene.

Prima di tutto probabilmente dovremo distribuire una versione di git (chiamiamola versione 2 per questa conversazione) che consente di avere uno slot per un nuovo valore di hash anche se non legge o usa quello spazio - usa solo il valore hash SHA-1 che si trova nell'altro slot.

In questo modo una volta che finalmente implementare ancora una nuova versione di git, chiamiamola la versione 3, che produce SHA-3 hash oltre a hash SHA-1, le persone che utilizzano la versione 2 git saranno in grado di continuare a inter-operare.
(Anche se, in questa discussione, possono essere vulnerabili e le persone che si affidano alle loro patch solo SHA-1 possono essere vulnerabili.)

In breve, passare a qualsiasi hash non è facile.


Aggiornamento febbraio 2017: sì, in teoria è possibile calcolare un SHA1 in collisione: shattered.io

Come viene influenzato GIT?

GIT si affida fortemente a SHA-1 per l'identificazione e il controllo di integrità di tutti gli oggetti file e commit.
È essenzialmente possibile creare due repository GIT con lo stesso hash di commit head e contenuti diversi, ad esempio un codice sorgente benigno e uno con backdoor.
Un utente malintenzionato può potenzialmente servire in modo selettivo uno dei repository per utenti target. Ciò richiederà agli aggressori di calcolare la propria collisione.

Ma:

Questo attacco ha richiesto oltre 9.223.372.036.854.775.808 calcoli SHA1. Ciò ha portato la potenza di elaborazione equivalente a 6.500 anni di calcoli a CPU singola e 110 anni di calcoli a GPU singola.

Quindi non farci prendere dal panico ancora.
Vedi di più su "In che modo Git gestirà una collisione SHA-1 su un blob? ".


8
Sembra che il recente raccolto di funzioni hash non crittografiche di alta qualità, come xxhash, sia uscito un po 'troppo tardi - subito dopo Git.
Prassolitico

3
@Praxeolitic davvero. Ci sono state discussioni sulla sostituzione di SHA1 con un altro hash, ma richiederebbe semplicemente un bel po 'di lavoro, per qualcosa che, per ora, sta funzionando bene.
VonC

"sappiamo che l'hash è ben distribuito e non dobbiamo preoccuparci di alcuni problemi di distribuzione" - perché questo è un problema per scm?
rodato il

@roded il tasso di collisione è abbastanza basso da essere adatto per un SCM in cui i dati non sono generalmente casuali ma file di test.
VonC

1
In realtà, esiste un motivo di sicurezza per l'utilizzo di un hash crittografico. Quando un autore (diciamo Linus) vuole tagliare una versione (diciamo Linux) le persone vogliono sapere il codice sorgente che scaricano corrisponde a ciò che l'autore intendeva includere nella versione. A tal fine, l'ultimo hash di commit nella versione è taggato e il tag è firmato. Se la catena hash di commit che termina con il tag non fosse crittograficamente sicura, la fonte potrebbe essere confusa con qualcosa di diverso da quello che l'autore intendeva.
Christopher King,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.