Protección mediante contraseña de cifrado y claves de firma

0

Me gustaría almacenar copias de seguridad cifradas de archivos de texto en mi computadora. Estoy desarrollando un script en Python usando Pycrypto para lograr eso, basado en el código este código para usar la biblioteca. ( código actual )

La idea básica es:

  1. Genere claves de firma AES + nuevas / leídas
  2. Cifre los datos utilizando la primera clave (AES 256-CBC)
  3. Firme los datos cifrados usando la segunda clave con HMAC-SHA256

La generación de bytes para las claves es simplemente el resultado de Random.get_random_bytes(KEY_SIZE + SIG_SIZE) , por lo que 64 bytes en mi caso.

Ahora, para mejorar la seguridad, me gustaría agregar una protección de contraseña a la clave (si alguien encuentra el archivo de claves). Mi idea inicial es hash salt + password y XOR el resultado con los bytes aleatorios en el archivo de clave.

Si uso SHA256 (para ser consistente), significa que produzco 32 bytes y debo XOR dos veces (por cada clave de 32 bytes) y no me gusta (no estoy seguro, pero suena como un posible ataque). ¿Usando una sal diferente para cada llave?

Finalmente, ¿hay una forma estándar para almacenar la sal y las claves? No me gusta la idea de inventar mi propio esquema (generalmente una mala idea en criptografía). ¿Hay algunas buenas prácticas ?

Actualización: gracias a la respuesta de Polynomial , obtuve el siguiente código :

from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2

def generate_new_keys(password, enc_key_size=32, sig_key_size=32):
    rand_bytes = Random.get_random_bytes(enc_key_size + sig_key_size)
    # save the salt
    with open('keys.salt','w') as f:
        f.write(rand_bytes.encode("base64").replace("\n",""))
    # derive the two keys using PBKDF2
    enc_key = PBKDF2(password, rand_bytes[:enc_key_size], dkLen=enc_key_size)
    sig_key = PBKDF2(password, rand_bytes[enc_key_size:], dkLen=sig_key_size)
    return (ency_key, sig_key)
    
pregunta Martin Trigaux 17.12.2012 - 12:05
fuente

1 respuesta

5

No intente crear su propio esquema de cifrado. El que propones es vulnerable a un ataque de texto simple conocido , lo que hace que el material clave sea trivial para recuperar si hay fragmentos del Se conocen los archivos originales.

Por ejemplo, si sé que el primer byte del texto sin formato siempre es 0x4B , y puedo ver que el primer byte del texto cifrado es 0xC7 , puedo calcular 0x4B ^ 0xC7 y obtener el primer byte de la clave , que sería 0x8C . Desde allí puedo omitir 32 bytes y descifrar ese byte de texto cifrado, y otra vez, y otra vez. Usando esa información, podría descubrir más información sobre su texto plano y usarla para descifrar más datos.

Cifre su archivo de clave con un cifrado de bloque (por ejemplo, AES) usando un modo de operación apropiado (por ejemplo, CBC), con una clave derivada usando un algoritmo de derivación de clave adecuado, como PBKDF2. El uso de una función hash simple para la obtención de claves es una mala idea, ya que es extremadamente rápido y le permite a un atacante descifrar la contraseña de manera eficiente. Si su modo de operación requiere un vector de inicialización (IV), debe ser aleatorio y único, pero no es información secreta.

    
respondido por el Polynomial 17.12.2012 - 12:11
fuente

Lea otras preguntas en las etiquetas