Hashing de dominio completo con tamaño de Hash variable en Python

Una función hash criptográfica es una clase especial de función hash que tiene ciertas propiedades que la hacen adecuada para su uso en criptografía. Es un algoritmo matemático que asigna datos de tamaño arbitrario a una string de bits de un tamaño fijo (una función hash) que está diseñado para ser también una función unidireccional, es decir, una función que no es factible de invertir. En este artículo, comprendamos uno de esos tipos de hash con tamaño de hash variable. 
Los esquemas tradicionales de RSA Signature se basan en la siguiente secuencia de pasos: 
 

  1. Obtener el mensaje a firmar digitalmente – M
  2. Use SHA o algún otro algoritmo hash para generar el resumen del mensaje: H = Hash (M)
  3. Cifre el resumen del mensaje con la clave privada del firmante. Los resultados del cifrado son la firma del mensaje: S = E (PrivateKey, H)

Un déficit potencial en el esquema ilustrado anteriormente es que el sistema RSA termina siendo infrautilizado . Supongamos que el módulo RSA es del orden de 2048 bits. Esto significa que la entrada puede ser cualquier valor con hasta 2048 bits. Sin embargo, en el esquema de firma, la entrada al sistema RSA es consistentemente del mismo tamaño, el tamaño del hash-digest. Por lo tanto, si, por ejemplo, se utiliza SHA-512 en el esquema de firma, todas las entradas a la función RSA serán consistentemente de 512 bits. Esto deja la mayoría ( > 99 % en este caso) del espacio de entrada de RSA sin utilizar. Esto tiene el efecto de reducir el nivel de seguridad general del sistema RSA como resultado de la infrautilización del espacio de entrada.
 

El esquema Full Domain Hashing (FDH) en los esquemas RSA Signature mitiga esta infrautilización al convertir el mensaje en el dominio completo del criptosistema RSA. El objetivo de FDH, por lo tanto, es:
 

Hash un mensaje usando una función cuyo tamaño de imagen/tamaño de resumen es igual al tamaño del módulo RSA 
 

Los dos enfoques básicos para realizar una función que puede producir un resumen de tamaño arbitrario son: 
 

  1. Hashing repetidamente el mensaje (con ligeras modificaciones) y concatenación
  2. Uso de métodos hash de función de salida extensible (XOF)

Hashing repetido con concatenación
Aunque los algoritmos hash tradicionales como SHA1, SHA256, SHA512 no tienen el rango suficiente para cubrir los dominios de entrada de los sistemas RSA, podemos construir un método hash de dominio completo mediante la aplicación repetida de estas funciones hash. La función hash estándar, digamos SHA512, se aplica al mensaje repetidamente, concatenando los resultados cada vez. Esto se hace hasta que se alcanza el número requerido de bits.
Para introducir el comportamiento aleatorio de las funciones hash, en lugar de aplicar hash al mismo mensaje repetidamente, se introducen algunas modificaciones al mensaje en cada iteración antes de realizar el hash. Un ejemplo de una modificación de este tipo sería concatenar el recuento de iteraciones al mensaje, antes del hash. Así, una función FDH se realiza como: 
FDH(m) =\ h(m\lvert\lvert0)\ ||\ h(m||1)\ ||\ h(m||2)\ || \dotso
Si el hash SHA512 se calculó y concatenó N veces, el hash general tendrá un tamaño de bit de N * 512 . Suponiendo que este valor es mayor que el número requerido, ‘K’ , de bits, podemos extraer los K bits principales para obtener el hash de longitud deseado.
A continuación se muestra la implementación del enfoque anterior:
 

Python3

# Python program to demonstrate
# repeated hashing with
# concatenation
 
import binascii
from math import ceil
from hashlib import sha256
 
# Function to perform Full Domain
# Hash of 'message' using
# SHA512 with a digest of
# N bits
def fdh(message, n):
     
 
    result = []
 
    # Produce enough SHA512 digests
    # to make a composite digest
    # greater than or equal to N bits
    for i in range(ceil(n / 256)):
 
        # Append iteration count
        # to the message
        currentMsg = str(message) + str(i)
 
        # Add current hash to results list
        result.append(sha256((currentMsg).encode()).hexdigest())
 
    # Append all the computed hashes
    result = ''.join(result)
 
    # Obtaining binary representating
    resAsBinary = ''.join(format(ord(x), 'b') for x in result)
 
    # Trimming the hash to the
    # required size by taking
    # only the leading bits
    resAsBinary = resAsBinary[:n]
 
    # Converting back to the
    # ASCII from binary format
    return binascii.unhexlify('00%x' % int(resAsBinary, 2)).hex()
 
# Driver code
if __name__ == '__main__':
    # Message to be hashed
    message = "GeeksForGeeks"
 
    # Generate a 600 bit
    # hash using SHA256
    print(fdh(message, 600))
Producción: 

00cf161c36df4db9e30d79cf9cb3d72e1934cbaeb9eb8638f0d71f1872679e1df9c3932c77c70c98efa64d34e3166c5b698738b36d9b36b87261c5ae3c61871bc3608ed19 

 

Uso de métodos hash de función de salida extensible (XOF)
Las funciones de salida extensible son una clase de funciones hash que, a diferencia de las funciones hash tradicionales, pueden generar una secuencia arbitrariamente grande de bits en el resumen de un mensaje. Esto contrasta fuertemente con las funciones hash regulares que se definen por un tamaño de salida fijo. En el esquema SHA-3 recientemente introducido, XOF se proporciona utilizando los algoritmos SHAKE128 y SHAKE256 . Se derivan de las propiedades generales de la construcción de la esponja . Una función de esponja puede generar una longitud arbitraria de la salida. Los 128 y 256 de sus nombres indican su máximo nivel de seguridad (en bits), tal como se describe en las Secciones A.1 y A.2 de FIPS 202 .
Para aprovechar la funcionalidad de SHA-3 en Python, la biblioteca PyCryptodome se puede utilizar de la siguiente manera:
 

Python3

# Python program to demonstrate
# the SHA-3 algorithm
 
from Crypto.Hash import SHAKE256
from binascii import hexlify
 
# Instantiate the SHAKE256 object
shake = SHAKE256.new()
 
# Set the message to be hashed
shake.update(b'GeeksForGeeks')
 
# Print a hash output of 50 bits size
print(hexlify(shake.read(50)))

Producción: 
 

b’65d6df8d88198de69b3cf59b859d72971b93f102ca20af812b931714a558c7a134cb3bb085835f470c890bd1d50928355358′ 
 

Nota: El código anterior no se ejecutará en los IDE en línea porque los IDE en línea carecen de la biblioteca Crypto. 
 

Publicación traducida automáticamente

Artículo escrito por tabmir y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *