From my research I learned that this is the correct way to wrap an AES session key using RSA:
import java.security.*;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class Main {
public static void main(String args[]) throws Exception {
KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES");
aesKeyGen.init(256);
SecretKey secretKey = aesKeyGen.generateKey();
Base64.Encoder encoder = Base64.getEncoder().withoutPadding();
Cipher cipher = Cipher.getInstance("RSA");
KeyPairGenerator rsaKeyGen = KeyPairGenerator.getInstance("RSA");
rsaKeyGen.initialize(4096);
KeyPair keyPair = rsaKeyGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedKey = cipher.wrap(secretKey);
cipher.init(Cipher.UNWRAP_MODE, privateKey);
SecretKey unwrappedKey = (SecretKey)cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
System.out.println(encoder.encodeToString(wrappedKey));
System.out.println(encoder.encodeToString(secretKey.getEncoded()));
System.out.println(encoder.encodeToString(unwrappedKey.getEncoded()));
}
}
My questions are:
- Should I keep using
Cipher.getInstance("RSA")
, switch toCipher.getInstance("RSA/ECB/PKCS1Padding")
or something else? - How can I do the same thing I am doing above but using EC?
- Is key wrapping the same as key encapsulation?
- Do I need to clear the memory used by
secretKey
in some way like we do with arrays (e.g.Arrays.fill(array, (byte)0)
) or just if callgetEncoded()
?
To answer my second question I found that I should use:
KeyPairGenerator ecKeyGen = KeyPairGenerator.getInstance("EC");
However I am not sure what to use here instead of <name>
:
Cipher cipher = Cipher.getInstance("<name>");
I also discovered that I can choose what curve to use by doing this:
...
ECGenParameterSpec ecsp = new ECGenParameterSpec("sect571k1");
ecKeyGen.initialize(571);
...
but again, I don't know what parameter should I use here instead of <name>
:
new ECGenParameterSpec("<name>");
I believe that some good candidates are the following:
secp521r1, nistp521, sect571r1, nistb571, nistb571, sect571k1, nistk571 nistk571, sect163r2
are there other options? Can you help me select the best one? Is it enough to instantiate an ECGenParameterSpec
object to set the initialization parameters of the EC KeyPairGenerator
?