# Proper way of doing encryption and authentication (PBKDF2 + AES)

I'm currently in the planning phase of an authentication and storage-ish service.

The client needs a file ("ENCFILE") which he will work with. This file will be encrypted with AES256, and stored on the server.

In order to authenticate and download the file, and decrypt it, the user will need:

The server must never have access to the password, since it will also be used to decrypt "ENCFILE" stored on the server, yet, the user must still be able to authenticate to the server somehow.

In order to decrypt the file, the client will need an IV, the AES256 key, and some HMAC-bits. So, that should be doable with a regular PBKDF2 SHA512 I guess.. (256 bits for AES, 96 bits for IV and 160 for SHA1 HMAC). Username for salt should be good? Then all things can be generated client-side.

Suggested solution for authentication to the server? SRP? But without risking the server to know/lower the security of the key for AES, so.. how to generate the shared secret? PBKDF2 in some other way/salt?

-
Is the communication channel with the server itself authenticated (that is, the server proved it is indeed the server) and secured or should that be done in the protocol itself too? – orlp Sep 17 '13 at 16:52
Run the output of PBKDF2 through HKDF-Expand to produce different values for different purposes. – CodesInChaos Sep 17 '13 at 16:53
@nightcracker HTTPS. Probably with some pinning. – Joey Sep 17 '13 at 19:02
@CodesInChaos So, I should just use PBKDF2 initially (password + username as salt?), and run the expand like 4 times with various string-based identifiers? E.g. -"aes", "iv", "hmac", and "srp-secret". Since this should solve the SRP thing also. So the username and the SRP secret (and a random salt for the SRP) is the only thing the server will ever have, and should never be able to speed up/deduce anything regarding the key (or even IV). – Joey Sep 17 '13 at 19:04
(and SRP is the way to go for authentication? A "simpler" zero-knowledge solution for the server would be nicer of course, but..) – Joey Sep 17 '13 at 19:09

PBKDF2 can produce output of arbitrary length. With HMAC/SHA-512 it does so in 512-bit chunks, but it is not restricted to 512 bits. If you need more bits then you can have more.

If you want to use the same password for authentication and for encryption, then the proper way is to "isolate" them from each other. I suggest the following: for the user password and salt (salt is on the server, and sent back when any client asks for it), the client computes PBKDF2 and obtains at least 256 bits. The first 128 bits will be used for authentication; the other 128 bits for encryption. Presumably, knowing the first half of the PBKDF2 yields no clue about the second half, and vice versa, except if the source password is guessed through exhaustive search (we are expecting PBKDF2 to behave like a Pseudorandom Function Family, the salt selecting the function in the PRF).

For authentication, use SRP indeed. For encryption, use GCM or EAX. GCM and EAX are nice encryption modes for AES (or other block ciphers, but primarily AES) which handle both symmetric encryption and a MAC, and can do so with relaxed requirements on the IV: these modes just need a non-repeating IV, not necessarily a random IV. You don't have to derive the IV from the password, and indeed you should not do it in case you want to encrypt several files with the same password, because then all the files will get the same IV, which is known to be a problem. Just encode the IV (counter, random... whatever floats your boat, depending on the encryption mode) in the file header.

It is not scientifically needed to use more than 128 bits for encryption or for authentication. Some people find psychological comfort in having huge keys, though.

It shall be noted that since the client first requires the salt from the server, an attacker impersonating the server could feed the client with a fake salt. Forcing the client to use a specific salt might allow for precomputations (aka "rainbow tables"). However, the SRP protocol ends with a pair of verification messages which validate that "everything went well" (when using SRP with TLS, the TLS Finished messages play that role). In the envisioned case, these messages not only guarantee to the client that it talked to the expected server, but also that the salt value was the right one, not one provided by an attacker.

-
The derived keys will only be used to encrypt that single file. However, there will be more files encrypted, but those will have random keys and IVs, and plaintext of "random" length (1B -> ~5MB). What is the suggested AES256 mode? – Joey Sep 18 '13 at 7:33
I do agree with @CodesInChaos that splitting the output of PBKDF2 is not always the best thing to do. The problem is that the number of iterations is repeated if more bytes are needed than the output of the underlying hash function. This is only an advantage to an attacker. For a protocol that does not rely specifically on the output of the hash function it seems better to use an additional KBKDF such as HKDF for key diversification. – Maarten Bodewes Sep 18 '13 at 20:03