¿Cuál es la mejor práctica para almacenar el vector de inicialización, clave privada y clave en la base de datos?

6

Estoy trabajando en la aplicación java para crear una firma digital para firmar un documento. Ya creé la clave privada y la clave pública usando ECC (criptografía de curva elíptica), y ahora quiero almacenar ambas claves en la base de datos mysql.

No tengo ningún problema con la clave pública, pero mi preocupación es almacenar la clave privada de forma segura.

Estoy usando AES de 128 bits para cifrar la clave privada y la contraseña de 6 dígitos del usuario para almacenar en la base de datos. Para cifrarlo, necesito generar sal e inicializar también el vector.

Pero ahora, para descifrarlo también necesito saber el mismo vector de inicialización y sal (iv) que utilizo para descifrar la clave privada cifrada.

Pregunta 1:

¿Es seguro almacenar sal y vectores en la misma base de datos con clave privada? Actualmente codifico claves públicas y privadas, salt y iv y las guardo como cadena (tipo de datos VARCHAR) en la base de datos.

Pregunta 2:

A continuación se muestra el flujo de trabajo actual que diseño. ¿Es esta la mejor práctica? No quiero hacer demasiado proceso que afecte el uso de la CPU.

Creando clave

  • Crear clave privada usando ECC
  • Codificar clave privada (Bytes a cadena)
  • Cifrar clave privada usando AES
  • Codifique la clave privada, sal, iv (Bytes a Cuerda)
  • Almacenar en la base de datos como VARHCAR

Documento de firma

  • Recuperar clave privada de DB
  • Decodificar clave privada, sal, iv
  • Descifrar clave privada
  • Decodificar clave privada
  • Convierta la clave decodificada en una clave privada real para firmar

Fragmento de código para generar la clave y el cifrado:

        //Generate salt
        Random r = new SecureRandom();
        byte[] salt = new byte[8];
        r.nextBytes(salt);
        //System.out.println("salt: "+salt);

        //initialize vector
        byte[] vector = new byte[128/8];
        r.nextBytes(vector);
        IvParameterSpec ivspec = new IvParameterSpec(vector);
        //System.out.println("iv: "+iv);

        //initialize variables
        String MsgToEncrypt = encodedECCprivateKeyBytes;
        String userPin = ParamUtil.getString(actionRequest, "userPin");
        Cipher ecipher;

        //Generating AES key
        SecretKeyFactory factory =  SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec mykeySpec = new PBEKeySpec(userPin.toCharArray(), salt, 10000, 128);
        SecretKey tmp = factory.generateSecret(mykeySpec);
        SecretKeySpec mySecretkey = new SecretKeySpec(tmp.getEncoded(), "AES");

        //==> Create and initiate encryption
        System.out.println("Initiate encryption alogrithm...");
        ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        //System.out.println("Algorithm to encrypt private key: " + ecipher);
        ecipher.init(Cipher.ENCRYPT_MODE, mySecretkey, ivspec);
        //System.out.println("SecKey: "+mySecretkey);
    
pregunta Mohamad Raziman Md Dom 19.01.2018 - 18:00
fuente

2 respuestas

7

Responderé su pregunta en dos partes, ya que la formuló en dos partes:

  

Pregunta 1:   ¿Es seguro almacenar sal y vectores en la misma base de datos con clave privada? Actualmente codifico claves públicas y privadas, salt y iv y las guardo como cadena (tipo de datos VARCHAR) en la base de datos.

Respuesta corta: Sí, es seguro.

Explicación: en general se acepta que mantener la sal en texto sin formato junto con la contraseña con hash es segura. Esto se basa en la lógica de que si un atacante tiene la sal y el hash, todavía debe utilizar un ataque de fuerza bruta para intentar adivinar la contraseña utilizada para crear el hash. Mantener la sal en secreto también mejoraría la seguridad, pero siempre que la contraseña sea razonablemente fuerte, no es necesario. Para el IV, es mucho más complicado y, en mi opinión, fuera del alcance entrar aquí (y fuera de mi zona de confort para explicar), pero se considera seguro que el IV se almacene en texto plano junto al cifrado. texto.

  

Pregunta 2:   A continuación se muestra el flujo de trabajo actual que diseño. ¿Es esta la mejor práctica? No quiero hacer demasiado proceso que afecte el uso de la CPU.

El flujo de trabajo me parece bien y es casi igual a como lo hubiera hecho, con algunos detalles, creo que puede mejorar ya que está solicitando las mejores prácticas:

  1. Primero, tu sal es un poco demasiado corta. El problema con esto es que con una sal de 8 bytes, incluso cuando se genera utilizando un generador criptoaleatorio (como usted, que es bueno), existe la posibilidad de colisiones donde dos o más usuarios diferentes tienen asignado el mismo valor de sal. Para mitigar esto, la recomendación que sigo es una longitud de sal de 256 bits o 32 bytes.

  2. Un segundo consejo y no estoy seguro de tu código si ya lo sabes, pero asegúrate de nunca volver a usar el mismo IV con la misma tecla AES dos veces. Debido al criptoanálisis muy sofisticado, esto puede crear vulnerabilidades en el cifrado que lo hace quebradizo. Dado que la clave se genera a partir de una contraseña de usuario que supongo que rara vez se cambia, asegúrese de girar el IV cada vez que vuelva a cifrar la clave privada.

  3. Parece que solo estás haciendo 10 000 rondas de hash en este momento. Aunque esto no es horrible, la regla de oro que siempre he seguido es de 2 ^ (año-2000) iteraciones. Como es 2018, la mejor práctica es obtener 250 000 iteraciones hash o lo más cerca que se pueda de este valor antes de alcanzar problemas graves de rendimiento.

De lo contrario, creo que todo se ve bien, hizo una buena elección en algoritmos de hashing y de clave pública-privada y fue sensato al buscar ayuda para asegurarse de que no pasó por alto nada.

Espero que ayude!

    
respondido por el dFrancisco 19.01.2018 - 19:39
fuente
3

Sí. Es seguro almacenar el Salt y el IV junto a la entrada encriptada.

Para entender por qué, debe profundizar en lo que están destinados a hacer la sal y la IV.

La sal es una forma de hacerlo para que, si se agrieta una entrada una , no se filtre a ninguna otra entrada. Si tuviera una tabla de contraseñas cifradas que no estaban borradas, tan pronto como alguien descifrara un registro, también descifraría simultáneamente todos los registros que compartían la misma contraseña descifrada. La sal no tiene la intención de hacer que la fuerza bruta sea más difícil; solo tiene la intención de garantizar que cada entrada se aísla de forma cifrada respecto a cualquier otra entrada. Por lo tanto, no importa si el atacante conoce la entrada de sal para cualquier registro dado, siempre que use una sal diferente para cada entrada, la sal está haciendo su trabajo.

Del mismo modo, la IV está destinada a detener los ataques conocidos de texto simple. Su objetivo es evitar que alguien explote "Todas estas entradas X comparten contenidos similares en Bytes X-Y" y usar el criptoanálisis para deducir aspectos de la Clave. La IV básicamente confunde los datos antes de su cifrado. Así que saber la IV tampoco ayuda al atacante.

Así que adelante, almacene el IV y el Salt junto con el valor cifrado.

    
respondido por el Kevin 19.01.2018 - 21:23
fuente

Lea otras preguntas en las etiquetas