John John - 3 months ago 22
Java Question

Public/private key to encrypt AES session key

I've been working on an encryption/decryption program. I am using AES.
What I am struggling with is, removing the

string password
and create a AES session key. This AES session key is what I actually want to use to encrypt and decrypt the data with. Then use the private or public key to encrypt this AES session key and stored locally (for example purposes).

Below is the coding which is currently fully working to encrypt and decrypt data with a plain text string:

Coding so far:

// password to encrypt the file
String password = "p@sswordDataNoW";

// salt is used for encoding
byte[] salt = new byte[8];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(salt);
FileOutputStream saltOutFile = new FileOutputStream("salt.enc");
saltOutFile.write(salt);
saltOutFile.close();

SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
128);
SecretKey secretKey = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

//padding AES encryption
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();

// iv adds randomness to the text and just makes the mechanism more
// secure
// used while initializing the cipher
// file to store the iv
FileOutputStream ivOutFile = new FileOutputStream("iv.enc");
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
ivOutFile.write(iv);
ivOutFile.close();

//file encryption
byte[] input = new byte[64];
int bytesRead;

while ((bytesRead = inFile.read(input)) != -1) {
byte[] output = cipher.update(input, 0, bytesRead);
if (output != null)
outFile.write(output);
}

byte[] output = cipher.doFinal();
if (output != null)
outFile.write(output);

inFile.close();
outFile.flush();
outFile.close();


Please could someone help me out, in terms of changing the
string password
to a session key that is generated. Then encrypt this session key with either the public or private key and stored on the local system.

I have tried many different ways and every time it has no worked out.

Answer

An AES key consists of either 16, 24 or 32 bytes and is supposed to look like random noise. The user is never going to see it. So, you can generate it securely:

SecureRandom r = new SecureRandom();
byte[] aesKey = new byte[16];
r.nextBytes(aesKey);

Here I generated a 16 byte key. You should use 24 or 32 byte for higher security, but only if you installed the Unlimited Strength policy files for your JRE/JDK.

Now, the remaining encryption is easy:

SecretKey secret = new SecretKeySpec(aesKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
// everything else as before

Separately from that you can encrypt aesKey with your public key. If you "encrypt" with a private key, you're not protecting the AES key from spying on. "Encrypting with a private key" is called signing and that data is not confidential.

Comments