Questo modo di codificare gli hash crittografici è sicuro?

12

Sto guardando il codice di una particolare applicazione web che gestisce i caricamenti di file. Per qualche ragione, invece di usare la funzione di hash crittografica (SHA-256 in questo caso), ne ricavano un ID e lo usano ovunque, per identificare i file in modo univoco.

I passaggi coinvolti sono i seguenti:

  • Calcola la somma SHA-256 del file richiesto.
  • Prendi un massimo di 3 caratteri per ogni iterazione e trattalo come una stringa esadecimale, convertilo nella sua notazione base62 equivalente (cioè 0-9a-zA-Z => 0 - 62 ).
  • Aggiungi queste stringhe in questo ordine e ottieni "ID".

Ad esempio:

hash (file) = 26ba0a896923d2de4cad532a3f05da725d9cc08d371eaf96905f5bbc1901b56f

26b  -------> 9Z
a0a  -------> Fs
896  -------> zs
923  -------> BJ
d2d  -------> Sp
e4c  -------> X2
ad5  -------> IJ
32a  -------> d4
3f0  -------> gg
5da  -------> oa
725  -------> tv
d9c  -------> Uc
c08  -------> NG
d37  -------> Sz
1ea  -------> 7U
f96  -------> 12m
905  -------> Bf
f5b  -------> 11p
bc1  -------> Mx
901  -------> Bb
b56  -------> KO
f    -------> f

ID = 9ZFszsBJSpX2IJd4ggoatvUcNGSz7U12mBf11pMxBbKOf

Per me, questo non sembra essere un modo sicuro per troncare l'hash a tutti. In particolare, mi sembra che la probabilità di collisioni aumenti in questo modo. *

Le operazioni di cui sopra rappresentano un problema o non interferiscono con i punti di forza crittografici di SHA256?

* Le resistenze delle funzioni SHA-2 possono impedire a un utente malintenzionato di sfruttarlo. Tuttavia, sono solo preoccupato per la premessa della funzione stessa.

    
posta S. B. 27.05.2015 - 17:49
fonte

5 risposte

30

Questo è quasi una pratica perfetta, ma ha un po 'di difetto.

In generale, un hash è solo un valore numerico e puoi esprimerlo in qualsiasi base tu voglia. Ad esempio, puoi convertire il tuo hash in binario ed esprimerlo come base64:

   2   6   b   a  ...
   |   |   |   |
0010011010111010  ...
      |      |
      T      u

Tuttavia, il problema serio con il tuo approccio qui è il clustering dell'output. Tre cifre esadecimali possono trasformarsi in una, due o tre cifre base62. Non esiste un modo affidabile per decidere come raggruppare i valori di base62. Se avevi zeri iniziali (cioè, hai trasformato tre cifre esadecimali in tre cifre base62) e / o hai usato una base più grande (ad esempio, tre cifre esadecimali potevano mappare esattamente su due cifre base128 con zeri iniziali), puoi evitare questo problema.

Per vedere un esempio pratico di questo, considera che esadecimale f43 mappa a base62 111 e 03f mappa su base62 11 . Considera l'impossibilità di distinguere tra le forme base62 degli hash seguenti:

f43f43f43f43f43f43f43f43f43f4303f03f03f03f03f03f03f03f03f03f9991
03f03f03f03f03f03f03f03f03f03ff43f43f43f43f43f43f43f43f43f439991
03ff4303ff4303ff4303ff4303ff4303ff4303ff4303ff4303ff4303ff439991

Tutti questi hash si trasformano in

11111111111111111111111111111111111111111111111111CC1

Non c'è modo di sapere quale 1 s fa parte di un gruppo di tre caratteri e fa parte di un gruppo di due caratteri. Ovviamente, questo è un esempio estremo, ma il problema si presenterà ogni volta che un gruppo ha un 1 che è ambiguo.

Tuttavia, i gruppi di uscita a tre e una cifra si verificano solo per 314 dei possibili 4096 valori che possono essere raggruppati, e ci sarà solo un'ambiguità per una frazione di questi casi. Un commento da Gilles , di seguito, stima che il valore troncato risultante conserverà 254 bit:

As far as we know, the bits of a SHA-2 hash are independent. This truncation doesn't exactly strip bits, but it's close enough that it should be independent too. The non-uniqueness concerns only about lg(12³-62²)≈0.1 bit per 3 hex digits, so the result should have roughly the strength of a 254-bit hash.

La perdita di due bit non è ovviamente ottimale, ma è lontana da una perdita devastante.

    
risposta data 27.05.2015 - 21:15
fonte
13

Da quello che posso vedere, questo non è affatto troncamento. Ogni sezione a 12 bit (3 caratteri esadecimali ASCII) viene convertita nella sua rappresentazione base62 equivalente, che è un'operazione bijective . Puoi prendere i valori a destra e reinserirli nei valori a sinistra.

L'operazione non tronca il valore, ma ne riduce la lunghezza risultante utilizzando una codifica più efficiente, proprio come calcolare il valore base64 dei byte hash grezzi.

    
risposta data 27.05.2015 - 18:15
fonte
3

"Troncare" significa rimuovere completamente una parte. In questo esempio, se ho troncato la metà destra dei caratteri hash, il resto sarebbe simile a questo: 26ba0a896923d2de4cad532a3f05da72

Quindi sì, il troncamento aumenterà le tue collisioni, ma non è quello che sta succedendo qui.

    
risposta data 27.05.2015 - 21:07
fonte
0

Se la lunghezza della rappresentazione esadecimale dell'hash non è accettabile, e si vuole rappresentare in modo univoco gli hash in una stringa più corta usando un set di caratteri limitato, usare base-64 piuttosto che base-64 consentirebbe una facile mappatura facile (anche se si deve sostituire . e / con caratteri diversi); se sono presenti solo 62 caratteri accettabili, è possibile suddividere i dati in blocchi a 64 bit e utilizzare 11 caratteri di base 62 per memorizzare ciascuno per una lunghezza totale fissa di 44, un solo carattere in più rispetto alla codifica di lunghezza fissa ottimale utilizzando 43 caratteri (la tua codifica a volte usa 43 caratteri, ma a volte richiede più e non sarebbe univoca). La codifica di 64 bit in base-62 dovrebbe essere ragionevolmente facile su qualsiasi piattaforma che abbia un tipo intero senza segno a 64 bit; su piattaforme che non lo fanno, si potrebbero codificare 53 bit come 11 caratteri di base 31 e aggiungere uno degli 11 bit rimanenti a ciascuno dei 31 caratteri di base per ottenere un carattere di base-32.

    
risposta data 28.05.2015 - 18:05
fonte
0

Non penso che ci siano abbastanza informazioni per dare una buona risposta. La possibile 'debolezza' con questo approccio è che riducendo la lunghezza della rappresentazione, si è aumentato il cambio di collisione. Due file con hash diversi possono finire con lo stesso codice trasformato. Tuttavia, questo potrebbe non essere un problema, a seconda dell'applicazione o il rischio di collisione può essere di minore preoccupazione rispetto alla necessità di ridurre la lunghezza della rappresentazione. non ci sono abbastanza informazioni per giudicare.

Tuttavia, detto questo, a prima vista, sembra difficile giustificare l'aumentato potenziale di collisione data la quantità minima di lunghezza di rappresentazione, specialmente considerando che se la lunghezza della rappresentazione è il problema, si presume che ci devono essere molti di questi hash da immagazzinare, il che significa che la collisione è probabilmente più probabile. Poi di nuovo, forse è tutto merito dell'aumento di efficienza ottenuto confrontando le firme più brevi dove le collisioni possibili non sono un problema

    
risposta data 28.05.2015 - 23:54
fonte

Leggi altre domande sui tag