0

Recently PHP7.2 was released with the Sodium library included for encryption.

Of course there were already encryption modules available, even working with Zend Framework 2 or Symfony. We were in need of an implementation for Zend Framework 3 and not wanting to rely on our own encryption method ideas, we created a ZF3 & Doctrine 2 module that uses paragonie's encryption implementation.

The purpose, at the moment, is to be able to automatically encrypt and decrypt on read/write of certain properties, detected via a listener hooked into the Doctrine ORM.

How we've set it up is the following:

Default

  1. Receive a string (do not encrypt null)
  2. Add in-code (config) salt to string
  3. Use in-code (config) private key for encryption

Obviously, not the strongest method of extending a string, but this is to make sure we can encrypt data marked with a tag using default settings. Data such as a street name.

Options

  1. Receive a string (do not encrypt null)
  2. Add generated 32 char salt and/or pepper before (and after) string (stored in separate db table, though records linked via foreign key)
  3. Add in-code (config) salt to string
  4. Use in-code (config) private key for encryption

This is the module we, actually just me, created. The actual implementation of the encryption/decryption starts about here.

  • processFields function - decides whether to encrypt/decrypt, passes values and, on decrypt, tries a type cast (to support value types) to return original value type
  • encrypt function - decides if salt and/or pepper need to be added based upon passed options. Then calls "encrypt" on adapter.
  • decrypt function - decides if salt and/or pepper were added based upon passed options. Removes them from string to return original string to encrypt.
  • Halite adapter - This is the default encryption/decryption adapter

Why am I asking?

Because I hope I've understood most everything right and thus created something awesome. However, as I'm not cryptology expert and we have no such person in-house, I thought to ask here, hoping to gain some feedback.

The code is provided as is and open source. It's extendable and re-usable so others can use the same service but can use their own encryption adapter. However, I wouldn't want them using something sub-par.

4
  • What are you trying to achieve by "salting"? Commented Apr 10, 2018 at 14:05
  • Making sure that no 2 the same received strings ("Welcome01") are encrypted the same and adding length (though I'm not sure how much of an impact the latter has). The default methodology adds the same salt, there it's just for added length/string complexity. The optional methods allow for additional salt, pepper or both, which could be generated at object creation to be unique per record.
    – rkeet
    Commented Apr 10, 2018 at 14:28
  • Salts are used for password hashing. Encryption uses initialization vectors, and this should already be handled by the library you use. Commented Apr 10, 2018 at 14:32
  • I honestly do not know if halite uses that. By default the module (after spicing things up) calls the encrypt function. The package's ReadMe does not mention it and at a certain point of following the code the cryptographic functions just go beyond me. Can the additional salt(s) (and pepper) hurt when encrypting/decrypting?
    – rkeet
    Commented Apr 10, 2018 at 14:39

1 Answer 1

1

What you did right

You're using a library

You chose to use a library to do the encryption for you. Good job! Somehow people still screw this up. Don't be a Dave, never roll your own crypto (unless you really, really understand what you're doing).

What you did wrong

You're misusing terminology

A salt is used when hashing passwords. It must be unique per password, and thus can't be located in a config. A pepper is similar to a salt, but it's the same for each password, and so it can be located in a config. Neither of these has anything to do with encryption.

You're trying to "improve" the encryption without understanding it

Adding a unique value to each string is unnecessary because (good) encryption algorithms use initialization vectors or nonces to randomize their output when encrypting duplicate data. Halite uses XSalsa20 MACed with a keyed BLAKE2b hash. Don't try to make it better, you'll just add complexity to your implementation for no reason.

There is a legitimate reason to pad data before encrypting, and that is to hide the length of the data. Some encryption algorithms allow an attacker to determine the length of the plaintext rounded to a number of bytes, and others allow to determine the exact length of the plaintext. In this case however you should pad all data to the same length (or a multiple of the same length), and the padding needn't be random.

5
  • Okidoki, so if I'm now understanding you right, what to do: - 1) remove the pepper, replace with the config salt. Use that for the hashing. (and if provided use the salt for the hashing bit) - 2) No need for the salt/peppers at all for normal encrypt/decrypt functionality as with the init vectors the duplicate results for the same strings are taken care of. As such, just use the asked for private key. Getting that right?
    – rkeet
    Commented Apr 10, 2018 at 18:05
  • @rkeet I don't see anywhere that you're doing password hashing, so there shouldn't be a salt or pepper anywhere. Commented Apr 10, 2018 at 18:16
  • Ah yes sorry, that was something wished for by the company and mentioned in that github repo of ours (readme file). But from that answer I conclude that for hashing: yes, salt (and maybe pepper) (as explained in your refs, thanks). For encryption: no, use the init vectors and supply only what's requested (a private key in the case of halite).
    – rkeet
    Commented Apr 10, 2018 at 18:29
  • [In this case however you should pad all data to the same length] - Why do you suggest that this should be done in this case? Is there a weakness in the XSalsa20, BLAKE20b or combination that allows determining the length of the plaintext, like you described?
    – rkeet
    Commented Apr 11, 2018 at 11:41
  • @rkeet This is more of an issue with cryptography in general than any particular algorithm. It's easy to overlook, and it's usually not an problem, but if you're not aware of it it can lead to things like CRIME and BREACH. Commented Apr 11, 2018 at 13:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .