La suma de comprobación de Code128 no es criptográficamente segura.
Creo que estás malinterpretando el propósito de una suma de comprobación. Una suma de control está diseñada para hacer posible detectar daños accidentales o errores en la lectura de datos. Los datos se convierten en una suma de comprobación y se comparan con la suma de comprobación esperada. Si los dos difieren, sabes que hubo un error al leer los datos. La intención es reducir la posibilidad de que un error accidental en la lectura resulte en la misma suma de comprobación. El algoritmo de suma de comprobación en sí es public y es fácil de calcular, como con la siguiente función, donde code128_table
es una tabla de índice específica (Código A, B o C):
uint8_t code128_checksum(uint8_t *buf, uint32_t len)
{
uint32_t sum = *buf - 32;
while (--len)
sum += len * code128_table[*(buf + len)];
return sum % 103 + 32;
}
Esta suma de comprobación es extremadamente simple, diseñada solo para hacer posible la detección de errores durante el proceso de escaneo. Es una suma "verdadera", lo que significa que no es más que la suma de las representaciones de cada carácter componente multiplicada por un factor de ponderación. Por lo tanto, la suma es literalmente solo eso, una suma de los datos que está protegiendo. No está diseñado para proporcionar ningún tipo de propiedades criptográficas al código de barras. La forma en que está diseñado, todo lo siguiente es trivialmente posible, en orden creciente de complejidad computacional:
-
Hashing : dado un código de barras sin suma de comprobación, calcule la suma de comprobación.
-
Colisión : crea dos códigos de barras con contenidos diferentes pero con una suma de comprobación idéntica.
-
Second preimage : dado un código de barras de suma de comprobación, cree otro con la misma suma de comprobación.
-
First preimage : solo con una suma de comprobación, crea un código de barras con la misma suma de comprobación.
Lo único en lo que es (modestamente) bueno es garantizar que un cambio aleatorio al código de barras no dará como resultado una suma de comprobación idéntica. Incluso por eso, no es particularmente bueno. Una suma de control superior (aunque no criptográficamente segura) del mismo tamaño de resumen sería CRC8, ya que un CRC es superior a un Suma de comprobación regular para la detección de errores. Una implementación simple de un CRC de 8 bits (donde crc8_table
es un cuidadosamente seleccionado polinomio de CRC de 8 bits se vería así:
uint8_t crc8(uint8_t *buf, uint32_t len)
{
uint8_t crc = ~0;
while (len--)
crc = crc8_table[crc ^ *buf++];
return crc;
}
Independientemente de si utiliza una suma de comprobación simple, CRC, o una mucho más compleja y lenta función hash criptográficamente segura , si el espacio de teclas no es más que 8 caracteres decimales y los 8 caracteres de la ID secuencial son válidos para el ID de la empresa B2DS, podría, de manera bastante trivial, crear todos los 99,999,998 códigos de barras posibles, con las correspondientes sumas de comprobación asociadas . Una implementación completamente no optimizada tomó 19 segundos en mi propia computadora. El espacio de teclas es demasiado pequeño, incluso con un hash criptográficamente seguro.
Como @Philipp mencionó en un comentario, una mejor solución sería entregar códigos de barras con una identificación aleatoria. Permita que cada ID se use un número limitado de veces y supervise los intentos de usar un código de barras con una ID que no se haya emitido explícitamente. Si se hace eso, entonces, incluso si hay mil códigos de barras válidos en un momento dado, un código de barras aleatorio solo tendría una posibilidad entre diez mil de ser válido, lo que hace que sea mucho más difícil usar los códigos de manera fraudulenta.