¿Esta forma de codificación de hashes criptográficos es segura?

12

Estoy viendo el código de una aplicación web en particular que maneja las cargas de archivos. Por alguna razón, en lugar de usar la función criptográfica hash (SHA-256 en este caso), derivan una ID de ella, y la usan en todas partes, para identificar los archivos de manera única.

Los pasos involucrados son los siguientes:

  • Calcule la suma SHA-256 del archivo requerido.
  • Tome un máximo de 3 caracteres por iteración y, tratándolo como una cadena hexadecimal, conviértalo a su notación base62 equivalente (es decir, 0-9a-zA-Z => 0 - 62 ).
  • Agregue estas cadenas en ese orden y obtenga la "ID".

Por ejemplo:

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

Para mí, esto no parece ser una forma segura de truncar el hash. En particular, me parece que la probabilidad de colisiones aumenta de esta manera. *

¿Las operaciones anteriores plantean un problema o no interfieren con las fortalezas criptográficas de SHA256?

* Las resistencias de las funciones SHA-2 pueden evitar que un atacante explote esto. Sin embargo, solo me preocupa la premisa de la función en sí.

    
pregunta S. B. 27.05.2015 - 17:49
fuente

5 respuestas

30

Esto es casi una práctica perfectamente buena, pero tiene un poco de falla.

En general, un hash es solo un valor numérico, y puedes expresarlo en la base que desees. Por ejemplo, podría convertir su hash a binario y expresarlo como base64:

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

Sin embargo, el problema serio con su enfoque aquí es el agrupamiento de la salida. Tres dígitos hexadecimales pueden transformarse en uno, dos o tres dígitos base62. No hay una manera confiable de decidir cómo agrupar los valores de base62. Si tuviera ceros iniciales (es decir, transformó tres dígitos hexadecimales en tres dígitos base62) y / o utilizó una base más grande (por ejemplo, tres dígitos hexadecimales se podrían asignar exactamente a dos dígitos base128 con ceros iniciales), podría evitar este problema. / p>

Para ver un ejemplo práctico de esto, considere que el hex f43 se asigna a base62 111 y 03f se asigna a base62 11 . Considere la imposibilidad de distinguir entre las formas base62 de los siguientes hashes:

f43f43f43f43f43f43f43f43f43f4303f03f03f03f03f03f03f03f03f03f9991
03f03f03f03f03f03f03f03f03f03ff43f43f43f43f43f43f43f43f43f439991
03ff4303ff4303ff4303ff4303ff4303ff4303ff4303ff4303ff4303ff439991

Todos estos hashes se transforman en

11111111111111111111111111111111111111111111111111CC1

No hay forma de saber qué 1 s son parte de un grupo de tres caracteres y cuáles son parte de un grupo de dos caracteres. Obviamente, este es un ejemplo extremo, pero el problema surgirá cada vez que un grupo tenga un 1 líder que sea ambiguo.

Sin embargo, los grupos de salida de tres y un dígito solo suceden para 314 de los 4096 valores posibles que el grupo puede tener, y solo habrá ambigüedad para una fracción de esos casos. Un comentario de Gilles , a continuación, estima que el valor truncado resultante conservará 254 bits:

  

Por lo que sabemos, los bits de un hash SHA-2 son independientes. Este truncamiento no elimina exactamente los bits, pero está lo suficientemente cerca como para que también sea independiente. La no unicidad solo concierne a lg (12³-62²) ≈0.1 bit por 3 dígitos hexadecimales, por lo que el resultado debería tener aproximadamente la fuerza de un hash de 254 bits.

La pérdida de dos bits obviamente no es óptima, pero está lejos de ser una pérdida devastadora.

    
respondido por el apsillers 27.05.2015 - 21:15
fuente
13

Por lo que puedo ver, esto no es truncamiento en absoluto. Cada sección de 12 bits (3 caracteres hexadecimales ASCII) se convierte a su representación base62 equivalente, que es una operación de bijective . Puede tomar los valores de la derecha y convertirlos de nuevo en los valores de la izquierda.

La operación no trunca el valor, sino que reduce su longitud resultante mediante el uso de una codificación más eficiente, al igual que calcular el valor base64 de los bytes de hash sin procesar.

    
respondido por el Polynomial 27.05.2015 - 18:15
fuente
3

"Truncar" significa eliminar una parte por completo. En este ejemplo, si truncara la mitad derecha de los caracteres hash, el resto se vería así: 26ba0a896923d2de4cad532a3f05da72

Así que sí, el truncamiento aumentará tus colisiones, pero eso no es lo que está sucediendo aquí.

    
respondido por el user77432 27.05.2015 - 21:07
fuente
0

Si la longitud de la representación hexadecimal del hash es inaceptable, y uno quiere representar hashes en una cadena más corta con un conjunto de caracteres limitado, usar base-64 en lugar de base-64 permitiría un mapeo fácil y agradable (incluso si uno tiene que reemplazar . y / con caracteres diferentes); si solo hay 62 caracteres aceptables, uno podría subdividir los datos en fragmentos de 64 bits y usar 11 caracteres base-62 para almacenar cada uno para una longitud total fija de 44, solo un carácter más que la codificación de longitud fija óptima con 43 caracteres (su codificación a veces usaría 43 caracteres, pero a veces requeriría más, y no sería única). La codificación de 64 bits en la base 62 debería ser razonablemente fácil en cualquier plataforma que tenga un tipo entero sin signo de 64 bits; en plataformas que no lo hacen, uno podría codificar 53 bits como 11 caracteres base-31 y agregar uno de los 11 bits restantes a cada uno de los caracteres base-31 para obtener un carácter base-32.

    
respondido por el supercat 28.05.2015 - 18:05
fuente
0

No creo que haya suficiente información para dar una buena respuesta. La posible 'debilidad' con este enfoque es que al reducir la longitud de representación, ha aumentado el cambio de colisión. Dos archivos con hashes diferentes pueden terminar con el mismo código transformado. Sin embargo, esto puede no ser un problema, dependiendo de la aplicación o el riesgo de colisión puede ser menos preocupante que la necesidad de reducir la longitud de representación. Realmente no hay suficiente información para juzgar.

Sin embargo, habiendo dicho eso, a primera vista, parece difícil justificar el aumento del potencial de colisión dada la cantidad mínima de longitud de representación, especialmente dado que si el problema es la longitud de la representación, supondría que debe haber una gran cantidad de estos hashes para almacenar, lo que significa que la colisión es posiblemente más probable. Por otra parte, quizás se trate del aumento de la eficiencia obtenida al comparar firmas más cortas donde las posibles colisiones no son un problema.

    
respondido por el Tim X 28.05.2015 - 23:54
fuente

Lea otras preguntas en las etiquetas