Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use Cipher.WRAP_MODE OR Cipher.ENCRYPT_MODE to encrypt a session key?

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?

like image 612
jusliang Avatar asked May 16 '13 11:05

jusliang


People also ask

Which of the following method of the cipher class completes the encryption operation?

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.

What is the use of cipher in Java?

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.


1 Answers

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

like image 174
Duncan Jones Avatar answered Dec 10 '22 09:12

Duncan Jones