# How to use Libsodium encryption (in PHP) in the most secure possible way?

In a PHP project in which fool-proof encryption is fundamental, I'm using the Libsodium library.

Hope you guys can shine some light on the following questions.

1. For all of the following functions, it looks like the length of the encrypted message is directly proportional to the length of the unencrypted message:

• sodium_crypto_secretbox
• sodium_crypto_box
• sodium_crypto_box_seal

It looks like no padding is used by default, correct ? This means that if within my setup I use different types of messages which each have a different length, an attacker can easily derive what kind of message it's about (without however knowing the content of the message), right ?

To mitigate this risk, I want to implement padding and I am looking for some advise on how to do this.

Is appending a random length random content (using random_bytes) message to the unencrypted message a good idea ? Does it make a difference whether I append it to the end of the message, at the beginning of the message or somewhere in the middle (or a combination of all) ? Are there more efficient ways to do this ?

2. If part(s) of the unencrypted messages are known, is it possible for an attacker to crack the encryption ? Or does it somehow becomes easier to do so ?

Example: if each encrypted message contains data delimited by for example "," or if each message starts/ends with a certain string or contains a certain string somewhere in the message, does this make attacks easier ? I mean, even when using padding an attacker might still know for sure part of the message's content.

I previously asked a question about how safe the encryption is (How safe are Libsodium Crypto Boxes?). Someone replied that 2^128 tries would be required to crack it. Does the amount of tries decrease if part of the message is known ? If yes by how much does it decrease ? What if someone knows the entire unencrypted message (for example the receiver) ? How easy/hard would it be for him to crack the senders' secret key ?

3. What about signed messages in Libsodium ? I know that signing does not encrypt the message but only appends a signature to it. How easy/hard is it to crack a SK based on a signature ? Could the receiver of a signed message potentially create a valid signature for a message not created by the sender ?

4. I read that nonces can be public without a problem. Nonetheless, does the fact that an attacker is in the possession of the nonce of a message decrease the cracking difficulty ?

5. Is it a good idea to change keypairs periodically to increase security ? Or doesn't this make sense ?

6. Does multi layer encryption make sense ? For example putting a crypto box inside another crypto box (with different keypairs off course). Or is this a bad idea ?

7. What about timing attacks ? I read that the time needed to decrypt/encrypt a message might give some clues about the SK. If Bob wants to crack Alices' SK, can he do so by analyzing how long it takes him to decrypt her message ? Or does it at least decrease the difficulty to do so ? If yes by how much ?

1. No need to implement padding, as it's already available. See the second example of the libsodium-PHP module.

2. Partially-known plaintext has no implication on security, especially in counter mode where the encryption of a block is independent from the previous blocks.

3. Creating a valid signature requires the secret key. Ed25519 has a 2^128 security target. The best attacks known actually cost more than 2^140 bit operations on average, and degrade quadratically in success probability as the number of bit operations drops.

4. Nonces can be public. Keeping them private doesn't significantly change the security level. However, nonces should never be used with different messages and the same key. See this page for a discussion on libsodium and nonces.

5. Yes. This doesn't make the cipher stronger, but mitigates the implications of a leaked secret key. If you are encrypting very large data streams, the secretstream API will automatically rotate the keys for you.

6. Salsa20 already has a huge key space. A salsa20-in-salsa20 cascade would have no benefits, and would be twice a slow.

7. Libsodium does its best to avoid side channels. Leaks are more likely to happen in the PHP code.

• You are my absolute cryptography hero :) ! With respect to the padding: I read that this requires the use of an additional variable (e.g. \$block_size = 16) and that both the sender as the receiver should know the value of this variable. Since this implies that this value has to be passed on from the sender to the receiver outside of the encrypted message, an attacker could intercept this and thus still know what the lenght of the real message is, or am I wrong ? As such, maybe it'a better to add a deliminator at the end of the message and append some random lenght string to it ? – Vincent Mertens Nov 28 '17 at 17:22
• Furthermore, would you mind to elaborate on "Leaks are more likely to happen in the PHP code" ? What should I pay attention to ? – Vincent Mertens Nov 28 '17 at 17:24
• Just make that a constant, or a parameter negotiated during an initial authenticated exchange. On side channels in PHP code: use the === operator to compare strings, you get a side channel. Convert the data to/from JSON, you get another one. Concatenate strings, another one. There's not much you can expect from an interpreted/JITed language anyway. – Frank Denis Nov 28 '17 at 17:42