How should I encrypt a session key on the client side with the public key transported from server side?
Should I use Cipher.WRAP_MODE
or Cipher.ENCRYPT_MODE
?
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedSessionKey = cipher.wrap(sessionKey);
I am not really sure how to use encrypt_mode to encrypt sessionKey. Could someone help me on this?
After initializing the Cipher object, we call the doFinal() method to perform the encryption or decryption operation. This method returns a byte array containing the encrypted or decrypted message.
It forms the core of the Java Cryptographic Extension (JCE) framework. In order to create a Cipher object, the application calls the Cipher's getInstance method, and passes the name of the requested transformation to it. Optionally, the name of a provider may be specified.
Wrapping and encrypting are very similar, however wrapping expresses more precisely what you are planning to do. General "encryption" operates on raw data with no semantic meaning, whereas wrapping is known to relate to keys. Hence the Cipher.unwrap()
method returns a Key
not a byte array.
Your code will be more portable (particular with respect to hardware security modules) if you use wrap for doing key wrapping. In some circumstances, key permissions will allow a wrapping operation but not a raw encryption of the key bytes.
Of course, since the entirety of the JCE architecture is based on a provider concept, you will need to check exactly what algorithm to specify for your chosen provider to get the output format you want. This is particularly important if you are sending the wrapped key data to a third-party.
In your particular case, the same behaviour will be exhibited by both WRAP
and ENCRYPT
, as demonstrated below, where I interchange the results:
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "SunJSSE");
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
SecretKey sessionKey = new SecretKeySpec(new byte[16], "AES");
Cipher c = Cipher.getInstance("RSA", "SunJCE");
c.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
byte[] result1 = c.doFinal(sessionKey.getEncoded());
c.init(Cipher.WRAP_MODE, keyPair.getPublic());
byte[] result2 = c.wrap(sessionKey);
c.init(Cipher.UNWRAP_MODE, keyPair.getPrivate());
SecretKey sessionKey1 = (SecretKey) c.unwrap(result1, "AES",
Cipher.SECRET_KEY);
c.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
SecretKey sessionKey2 = new SecretKeySpec(c.doFinal(result2), "AES");
System.out.println(Arrays.equals(sessionKey1.getEncoded(),
sessionKey2.getEncoded()));
This prints: true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With