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);