5

I was tasked with writing a small Java console application that involves encryption. I am not familiar with encryption, so I had to do some reading up first. So far the high level requirements given is that AES-256 should be used to generate a one-time key to encrypt a file.

After that, the recipient's public key (RSA-2048) should be used to encrypt that AES-256 one-time key. The encrypted file and the encrypted one-time AES-256 key will then be zipped up and send to recipient.

From what I understand about encryption and decryption from reading up, apart from the algorithm (RSA, AES, etc), there is also things called mode and padding. For example, the following code specified RSA as algorithm, ECB mode and PKCS1Padding.

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

The same algorithm, mode and padding must be used in the encryption and decryption. Therefore, is it reasonable for me to go ask the users on what mode and padding they want?

I notice that Cipher cipher = Cipher.getInstance("RSA") seems to use the default mode of ECB and padding of PKCS1Padding, and so this line of code is the same as the above. So is it ok to assume that ECB mode and PKCS1Padding mode will be used for RSA-2048 as default?

Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225
user3573403
  • 1,558
  • 1
  • 29
  • 52

2 Answers2

3

No, for sending messages you should use the newer OAEP scheme, as RSA with PKCS#1 v1.5 may be vulnerable to the Bleichenbacher attack. It is however entirely probable and even likely that somebody requesting RSA hybrid encryption has never heard of the attack. In general PKCS#1 v1.5 padding is still used as the default.

You should never expect users to make security decisions for you, unless the only users are students of cryptography (and know about the attack above). Security in general should not rely too much on educating users.

Personally I would certainly asking the requester about the padding. You should also check if they would expect authentication (MAC, HMAC, authenticated cipher or a signature) for the symmetric encryption. If he/she cannot answer the question they may not know that much about encryption.

I would not currently consider the requirements you have been given to be complete (although "for learning purposes" can be one hell of an excuse).

Notes

"RSA/ECB/PKCS1Padding" actually doesn't implement ECB mode encryption. It should have been called "RSA/None/PKCS1Padding" as it can only be used to encrypt a single block of plaintext (or, indeed a secret key). This is just a naming mistake of Sun/Oracle.

There is also a hybrid encryption mode called RSA-KEM that should be at least as secure as RSA OAEP, but it has not been implemented within Java SE.

AES-256 itself should not be used to "generate a one time key". You should use an instance of KeyGenerator generate an AES-256 one time key (this is likely a bit of naming confusion because the KeyGenerator itself does not use AES, it creates keys for AES).

Community
  • 1
  • 1
Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225
  • I can use the following code to generate the AES-256 one time key: KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256); SecretKey secretKey = keyGenerator.generateKey(); – user3573403 Jan 11 '15 at 14:03
  • Yeah, that's fine too. Does the same thing underneath but it's more clear. Amended answer to use your solution. The AES key generator does not use AES which was more or less implied in your question ("is that AES-256 should be used to generate a one-time key"), hence the note. – Maarten Bodewes Jan 11 '15 at 14:04
  • Based on the replies, I think I would have to ask the requester about the mode and padding. The requester is probably technical people like me. – user3573403 Jan 11 '15 at 14:08
  • Absolutely agree on that. Hopefully they are sensible people that accept sensible questions. PKCS#1 v1.5 is more likely to be meant, but as it may be insecure, you'd better be 100% certain and explain to them that it should not be used. Point to this answer if they have doubts. – Maarten Bodewes Jan 11 '15 at 14:11
  • This was given: "After validating the certificate, use the public key from the recipient’s certificate to encrypt the AES 256 key and specify 'PKCS7 with Padding'". So what should the mode be? According to what @Tom L said below, the key is smaller than one block, so block mode and padding are all irrelevant. – user3573403 Jan 12 '15 at 08:16
2

You do not want to be asking the users about padding or block mode. What I think that you need to do is:

Generate a random 256bit key (make sure you use a cryptographic library to do this, with good seeding)

Encrypt the file using AES256 with the key (DO NOT USE ECB, use CBC and possibly padding if you want to slightly conceal the exact length of the file)

Encrypt the key using RSA-2048 (here block mode from a security point of view is irrelevant because the key is smaller than one block, as is padding because the key is a known length. I would use ECB)

Your protocol gives no guarantees of who sent the file or integrity of the file. This is really important to think about, consider signing.

Unfortunately when implementing anything to do with crypto, you are extremely likely to get things wrong. Definitely use the Java libraries and if you can find higher level trusted libraries doing things closer to exactly what you want, consider using those.

Tom L
  • 121
  • 1