Como ejercicio, estoy escribiendo un código que acepta una lista de propiedades posiblemente secretas (por ejemplo, ID de usuario, contraseña, dirección IP), agrega una marca de tiempo, la cifra y la firma.
Aquí hay una descripción general de alto nivel de lo que hace el código: ¿se ve bien desde el punto de vista de que debería garantizar el secreto y la integridad?
Lo principal sobre lo que no estoy seguro es en derivar la clave de cifrado y la clave de firma a partir de la misma clave secreta proporcionada por el usuario, pero esto parece un poco paranoico ya que no debería haber una relación entre los dos asumiendo la fuerza del subyacente Función hash del algoritmo de derivación de claves.
Si a alguien le interesa el código fuente junto con un pequeño conjunto de pruebas, empaquetado con setuptools, puede encontrar aquí .
Implementación
El usuario proporciona una clave privada y dos sales opcionales que utilizamos para derivar claves de cifrado y firma mediante PBKDF2. Si no se proporciona sal, se generan dos utilizando urandom
.
A continuación, el usuario proporciona una lista de cadenas de propiedades, ['a', 'b', 'c',...]
que se convierte en una cadena | delimitada y a la que se añade str(time.time())
. Este texto simple se rellena utilizando el método PKCS # 7. Se genera un Vector de Inicialización (IV) usando urandom
y el texto simple se encripta con AES-256 (modo CBC) usando la clave descrita anteriormente y la IV.
Luego, el texto cifrado IV + se firma utilizando la implementación nativa de Python HMAC-MD5 con la clave de firma derivada como se describe anteriormente, y esta firma se adjunta al mensaje.
El proceso de descifrado y verificación sigue aproximadamente el proceso opuesto al anterior, con un cuidado especial en el paso de verificación para utilizar el método compare_hash
incorporado para evitar la vulnerabilidad debido al ataque de tiempo.