es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Fallo en la verificación de firma HMAC-SHA-256 en el inicio de sesión web de Telegram.

Estoy tratando de agregar el inicio de sesión de Telegram Web a mi proyecto Django+Vue. Estoy manejando el inicio de sesión en Vue y pasando directamente los datos de autorización obtenidos de TG a Django a través de DRF. Eso funciona bien. El problema ocurre en la verificación en la vista POST de REST. Cuando usaba la biblioteca js-sha256 en Vue, funcionaba perfectamente y obtenía el valor verdadero de la cadena hash proporcionada por la función sha256.hmac() de la biblioteca js-sha256. Estoy luchando por obtener la misma hash en Python. Aquí se explica la verificación de datos de TG y el código que estoy usando en la vista POST:

class TelegramLoginSerializer(serializers.Serializer):
    raw_data = serializers.JSONField(required=True)

def create(self, validated_data):
    raw_data = validated_data['raw_data']
    tg_data = "\n".join([f'{k}={raw_data[k]}' for k in sorted(raw_data)])

    if raw_data['hash'] != self.verify_telegram_data(tg_data):
        return PermissionDenied()
    else:
        ...

@staticmethod
def verify_telegram_data(data):
    secret_key = hashlib.sha256(settings.TG_BOT_TOKEN.encode('utf-8'))
    message = data.encode('utf-8')
    return hmac.new(secret_key.digest(), message, hashlib.sha256).hexdigest()

Aquí se explica la verificación de datos de TG y el código que estoy usando en la vista POST.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución para obtener el mismo hash en Python que el de la biblioteca js-sha256

    El problema parece estar en la codificación de la clave secreta y el mensaje utilizados para HMAC. Para obtener el mismo hash en Python que el de la biblioteca js-sha256, debes hacer los siguientes cambios:

    1. La clave secreta debe ser codificada con binascii.unhexlify() antes de ser utilizada para HMAC. Esto se debe a que TG_BOT_TOKEN está en formato hexadecimal.
    2. El mensaje debe ser codificado como bytes con str.encode(). Esto asegura que el mensaje de entrada para HMAC también esté en formato de bytes.

    Aquí tienes una implementación actualizada del método verify_telegram_data():

    @staticmethod
    def verify_telegram_data(data):
        secret_key = binascii.unhexlify(hashlib.sha256(settings.TG_BOT_TOKEN.encode('utf-8')).hexdigest())
        message = data.encode('utf-8')
        return hmac.new(secret_key, message, hashlib.sha256).hexdigest()
    

    Con estos cambios, el hash generado en Python debería coincidir con el de la biblioteca js-sha256.

Comments are closed.