objects - Python3 y hmac. Cómo manejar cadenas que no sean binarias.
python3 unicode objects must be encoded before hashing (2)
No para resucitar una vieja pregunta, pero sí quería agregar algo que siento que falta en esta respuesta, a la que tuve problemas para encontrar una explicación / ejemplo apropiado de cualquier otro lugar:
OP Aquiles Carattino estuvo bastante cerca con su intento de convertir la cadena en bytes, pero le faltaba el segundo argumento, la codificación de la cadena para convertirla en bytes.
Si alguien desea convertir una cadena a bytes a través de algún otro medio que no sea la asignación estática (como leer un archivo de configuración o una base de datos), lo siguiente debería funcionar:
import hmac, hashlib
def _generate_signature(data):
key = ''key'' # Defined as a simple string.
key_bytes= bytes(key , ''latin-1'')
data_bytes = bytes(data, ''latin-1'') # Assumes `data` is also a string.
return hmac.new(key_bytes, data_bytes , hashlib.sha256).hexdigest()
print(
_generate_signature(''this is my string of data'')
)
Tenía un script en Python2 que estaba funcionando muy bien.
def _generate_signature(data):
return hmac.new(''key'', data, hashlib.sha256).hexdigest()
Donde los datos fueron la salida de json.dumps
.
Ahora, si intento ejecutar el mismo tipo de código en Python 3, obtengo lo siguiente:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.4/hmac.py", line 42, in __init__
raise TypeError("key: expected bytes or bytearray, but got %r" %type(key).__name__)
TypeError: key: expected bytes or bytearray, but got ''str''
Si intento algo así como transformar la clave a bytes así:
bytes(''key'')
yo obtengo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
Todavía estoy luchando para entender las codificaciones en Python 3.
Puedes usar bytes literal: b''key''
def _generate_signature(data):
return hmac.new(b''key'', data, hashlib.sha256).hexdigest()
Además de eso, asegúrese de que los data
también sean bytes. Por ejemplo, si se lee desde un archivo, debe usar el modo binary
( rb
) al abrir el archivo.