2

We provide web redirection based integration with our partners' web apps. The flow is something like the following, and the password is generated randomly and shared with them during the onboarding process and before any interaction can take place and does not change often.:

  • Partner exposes web application to end user. End user submits a request to partner server.
  • Partner encrypts request using AES, and AES key generated using PBKDF2 along with a random salt and iteration count of 65536 and keylength 256
  • Partner sends a web redirection, and embeds the encrypted request in the GET request along with salt
  • Our server receives the request, Generates key using password and salt and decrypts request.

The encrypted request is small, not more than half a kilobyte. So encryption/decryption itself is fast.

The issue is with PBKDF2 key generation as it has to be computed every time because of salt. It is very slow because of the high iteration count, and hence takes about 100ms for each request. This is unacceptable as the number of redirections can be very high, and the server will not be able to keep up with incoming requests.

I went through this link (At what point does adding more iterations to PBKDF2 provide no extra security?) and some other similar discussions, which lead me to think that if I have a long random password, then I may be able to get away with a shorter iteration count (say 1000 or even 100).

Another thought I had was to pre-compute a 256 bit key using PBKDF2 with a high iteration count of say 65536, and then use that as password. Then for each request, compute the key using this password and the salt received in the request, pass them to the PBKDF2 with a smaller iteration count (say 1000 or 100). Would this approach be equally secure to the current implementation? or are there any issues with this?

My question may be similar to this: PBKDF2 used to generate an encryption key: long shared secret (password) vs iterations count however the answers were not very clear to me.

praveenp
  • 21
  • 1

1 Answers1

3

If you're just sharing the password out of band, and its only use is to derive a key, and the key must be derivable on both ends... why not just generate and share the key? Generate 128-256 bits of cryptographically random data, distribute that instead of any "password", and just use that. It's faster, simpler, and just as secure as your usual approach so long as you generate a random IV/NOnce for each encryption (if you use certain cipher modes, such as GCM, you'll need to re-key after sufficiently large amounts of data, but with your tiny messages that shouldn't be a problem unless you're sending/receiving them constantly at high rate).

If you care about the key itself being different each time (which you shouldn't, with a good mode of operation, but OK...) then generate a random value each time, HMAC the pre-shared key with that value, and use the resulting MAC as the key. Attach the random value (in plaintext) to the message.

CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • Thanks. The password is in fact generated as a random 128 bit (using java SecureRandom) converted to alphanumeric 16 bytes text and shared out of band with the partner and does not change. So are you saying, if I'm already doing this, then there is no need to use per-request salt and regenerate the key? Instead, the partner could generate a random IV and share it along with request, and use that with the key (shared out of band and also stored locally) and iv in the AES decryption correct? – praveenp Aug 22 '21 at 07:55
  • Yep, if you're already sharing a securely random 128 bit string, just use AES-128 (or any other secure modern cipher with a 128-bit key length) with the "password" as the key. The client will need to generate an IV/nonce for each message (the terminology depends on the mode of operation but the concept is the same), and send it in plain text along with the message, but presumably you're already doing that. If you want to use AES-256 instead without re-distributing the "password", just hash the "password" once with SHA-256 and re-store that as the key. – CBHacking Aug 22 '21 at 08:34
  • Thank you very much for the quick response. This is very helpful. – praveenp Aug 22 '21 at 08:42