paragonie / halite

High-level cryptography interface powered by libsodium
https://paragonie.com/project/halite
Mozilla Public License 2.0
1.12k stars 85 forks source link

Migrate from v2 to v4 #123

Closed vl-lapikov closed 5 years ago

vl-lapikov commented 5 years ago

Hey Guys,

All our strings now encrypted with halite v2 running on php 7.0 with php-libsodium_1.0.6. We want to migrate to halite v4, php 7.2 and use built-in Sodium php extension.

Though v4 can't decrypt messages encrypted by v2. The only reason I see, is removed config in this commit https://github.com/paragonie/halite/commit/b138802a5b0110165add53bbe7fa7e88a9b128a8#diff-9da2e1db2d19cfcea3a3f52530138f85L74. If I restore the config, it works just fine.

paragonie-scott commented 5 years ago

Halite, as a rule, only allows backwards compatibility by one major version at a time. This is to limit the efficacy of downgrade attacks (should one be discovered).

vl-lapikov commented 5 years ago

Thank you for quick answer!

We will restore the config in forked version to be able to support v2 encrypted strings. Later when all strings are migrated to v4, we drop the support for v2, so we can go back and use halite from composer.

nielsradstake commented 5 years ago

Halite, as a rule, only allows backwards compatibility by one major version at a time. This is to limit the efficacy of downgrade attacks (should one be discovered).

I understand the reasoning behind this, but when you have encrypted data that you cannot re-crypt (e.g. you don't have the keys and you depend on users logging in) you can't upgrade PHP and Halite unless you fork the repo and make it backwards compatible by yourself. I consider using older PHP versions or making changes to this project by a non-crypto expert a greater risk than decrypting strings that have been encrypted with an earlier version of this library.

paragonie-scott commented 5 years ago

If someone needs a decrypt-v2-only bridge for migrating to v4, that's something Paragon can create.

However, I can't give a promise that we'll be able to do this today. There's a lot on our plates, and paid work has to come first.

nielsradstake commented 5 years ago

Thanks for your quick answer!

I think the best solution is to change the Symmetric Config's getConfigEncrypt method and add config for all released versions (even version 1), so you can always decrypt data that you have encrypted using Halite. This way users of Halite can upgrade to the latest (and safest) version more easily while not worrying about previously encrypted data (that they sometimes cannot re-crypt). This improves the overall security by allowing everyone to keep up-to-date.

I agree that it is better to re-crypt and understand your reasons to drop support, but I really do think that the tradeoff of simplicity vs. security is a bit too much on the security side here.

paragonie-scott commented 5 years ago

I think the best solution is to change the Symmetric Config's getConfigEncrypt method and add config for all released versions (even version 1), so you can always decrypt data that you have encrypted using Halite.

This is specifically not going to happen.

What might happen is a separate bridge is created, which is out-of-scope for any bug bounty programs, that facilitates decryption all the way back to v1.

This does a few things:

  1. It doesn't leave downgrade attacks in our code indefinitely.
  2. It doesn't bloat our code with features that are no longer relevant.
  3. It doesn't force Halite users to have legacy cryptography protocols installed on their application unless they explicitly need them.
nielsradstake commented 5 years ago

Ok, clear. In that case I think I will drop Halite and implement Sodium directly instead so I have a stable interface. I chose Halite because of its simple, elegant interface, but not being able to read previously encrypted data after upgrading is a bit of a game changer for me (and presumably others).

paragonie-scott commented 5 years ago

It's February 2019. Halite v4.0 came out in September 2017, before libsodium was part of the PHP core. It's compatible with Halite v3.x, which came out in July 2016.

If you're worried about not having a "stable" interface, you're missing some context.

nielsradstake commented 5 years ago

The point is not that the interface of function calls etc. changed, because it didn't. With minor changes you can update all the way from v1 to v4. That should not be a problem for anyone.

However, not being able to decrypt data with the same library as you used to encrypt it only 3 years ago with a perfectly secure algorithm is something that does not work for me. I really like Halite and what you have done with it, but this policy of having no backwards compatibility means I have to drop it.

The way password_hash() is implemented in PHP seems like a better idea to me: use a better algorithm if it is available, but allow checking older hashes even though the algorithm used to hash them is not the best available today.

Again: great work 👍

paragonie-scott commented 5 years ago

I have a simple an elegant solution to all of this: I'm making a separate library called halite-legacy that will contain e.g.

This library will stand separately from Halite and will be explicitly excluded from our bug bounty programs.

paragonie-scott commented 5 years ago

https://github.com/paragonie/halite-legacy