Estoy tratando de construir dos funciones usando PyCrypto que acepten dos parámetros: el mensaje y la clave, y luego cifrar / descifrar el mensaje.
Encontré varios enlaces en la web para ayudarme, pero cada uno de ellos tiene fallas:
Este en codekoala usa os.urandom, que es desaconsejado por PyCrypto.
Además, no se garantiza que la clave que le doy a la función tenga la longitud exacta esperada. ¿Qué puedo hacer para que eso suceda?
Además, hay varios modos, ¿cuál se recomienda? No sé qué usar: /
Finalmente, ¿qué es exactamente el IV? ¿Puedo proporcionar un IV diferente para cifrar y descifrar, o esto devolverá un resultado diferente?
Editar : se eliminó la parte del código porque no era segura.
/dev/urandom
en UnixRespuestas:
Aquí está mi implementación y funciona para mí con algunas correcciones y mejora la alineación de la clave y la frase secreta con 32 bytes y iv a 16 bytes:
fuente
Es posible que necesite las dos funciones siguientes:
pad
- para rellenar (cuando se realiza el cifrado) yunpad
- para desempaquetar (cuando se realiza el descifrado) cuando la longitud de entrada no es un múltiplo de BLOCK_SIZE.Entonces, ¿estás preguntando la longitud de la clave? Puede usar el md5sum de la clave en lugar de usarlo directamente.
Además, según mi poca experiencia en el uso de PyCrypto, el IV se usa para mezclar la salida de un cifrado cuando la entrada es la misma, por lo que el IV se elige como una cadena aleatoria, y se usa como parte de la salida de cifrado, y luego Úselo para descifrar el mensaje.
Y aquí está mi implementación, espero que sea útil para usted:
fuente
pad
función está rota (al menos en Py3), reemplácelas[:-ord(s[len(s)-1:])]
para que funcione en todas las versiones.Déjame abordar tu pregunta sobre los "modos". AES256 es una especie de cifrado de bloque . Toma como entrada una clave de 32 bytes y una cadena de 16 bytes, llamada bloque, y genera un bloque. Utilizamos AES en un modo de operación para encriptar. Las soluciones anteriores sugieren usar CBC, que es un ejemplo. Otro se llama CTR, y es algo más fácil de usar:
Esto a menudo se conoce como AES-CTR. Aconsejaría precaución al usar AES-CBC con PyCrypto . La razón es que requiere que especifique el esquema de relleno , como lo demuestran las otras soluciones dadas. En general, si no tienes mucho cuidado con el relleno, ¡ hay ataques que rompen completamente el cifrado!
Ahora, es importante tener en cuenta que la clave debe ser una cadena aleatoria de 32 bytes ; Una contraseña no es suficiente. Normalmente, la clave se genera así:
También se puede derivar una clave de una contraseña :
Algunas soluciones anteriores sugieren usar SHA256 para derivar la clave, pero esto generalmente se considera una mala práctica criptográfica . Consulte wikipedia para obtener más información sobre los modos de operación.
fuente
Para alguien a quien le gustaría usar urlsafe_b64encode y urlsafe_b64decode, aquí está la versión que me funciona (después de pasar un tiempo con el problema Unicode)
fuente
Puede obtener una frase de contraseña de una contraseña arbitraria mediante el uso de una función hash criptográfica ( NO de Python incorporada
hash
) como SHA-1 o SHA-256. Python incluye soporte para ambos en su biblioteca estándar:Puede truncar un valor hash criptográfico simplemente usando
[:16]
o[:24]
y retendrá su seguridad hasta la longitud que especifique.fuente
Agradecido por las otras respuestas que inspiraron pero no funcionaron para mí.
Después de pasar horas tratando de averiguar cómo funciona, se me ocurrió la implementación a continuación con la biblioteca PyCryptodomex más nueva (es otra historia de cómo logré configurarlo detrás del proxy, en Windows, en un virtualenv .. phew)
Trabajando en su implementación, recuerde anotar los pasos de relleno, codificación y cifrado (y viceversa). Tienes que empacar y desempacar teniendo en cuenta el pedido.
fuente
Para el beneficio de otros, aquí está mi implementación de descifrado a la que llegué combinando las respuestas de @Cyril y @Marcus. Esto supone que esto llega a través de Solicitud HTTP con el texto cifrado citado y codificado en base64.
fuente
Otra versión de esto (fuertemente derivada de las soluciones anteriores) pero
probado con python 2.7 y 3.6.5
fuente
He usado ambos
Crypto
y laPyCryptodomex
biblioteca y es increíblemente rápido ...fuente
Es un poco tarde, pero creo que esto será muy útil. Nadie menciona el esquema de uso como el relleno PKCS # 7. En su lugar, puede usar las funciones anteriores para rellenar (cuando realiza el cifrado) y desempaquetar (cuando realiza el descifrado) .i proporcionará el código fuente completo a continuación.
fuente
codificación compatible utf-8
fuente
fuente