I am working on java application to create a digital signature to sign a document. I already created private key and public key using (Elliptic-curve cryptography) ECC, and now I want to store both keys in mysql database.
I dont have any problem with public key, but my concern is to securely store the private key.
I'm using AES 128 bit to encrypt the private key and 6 digit password from user to store in database. To encrypt it, I need to generate salt and initialize vector as well.
But now, to decrypt it I also need to know same salt and initialization vector (iv) I use to decrypt the encrypted private key.
Question 1:
Is it secure to store salt and vector in database same table with private key? Currently I encode public and private keys, salt and iv and save as string (data type VARCHAR) in database.
Question 2:
Below is current workflow I design. Is this the best practice? I dont want to make too much process that will affect CPU usage.
Creating key
- Create private key using ECC
- Encode private key (Bytes To String)
- Encrypt private key using AES
- Encode private key, salt, iv (Bytes To String)
- Store in database as VARHCAR
Signing document
- Retrieve private key from DB
- Decode private key, salt, iv
- Decrypt private key
- Decode private key
- Convert decoded key to actual private key for signing
Code snippet to generate key and encryption:
//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);
String
to encrypt presumably you can convert frombyte[]
toString
without base64 encoding (which causes a size increase).