resilar / sqleet

SQLite3 encryption that sucks less
The Unlicense
378 stars 56 forks source link

sqleet vs. SQLCipher comparison #12

Open resilar opened 6 years ago

resilar commented 6 years ago

A brief comparison of SQLCipher and sqleet features. Last updated: 2019-02-17

General

_ SQLCipher sqleet
First release November 2008 September 2017
SQLite version v3.26.0 v3.27.1
Lines of code ~3785 ~1385
License BSD Public domain

Cryptographic primitives (default configuration)

_ SQLCipher sqleet
Cipher AES-256-CBC ChaCha20
Authentication HMAC-SHA512 Poly1305
Key derivation PBKDF2-HMAC-SHA512 PBKDF2-HMAC-SHA256
PBKDF2 iterations 256000 12345

Cryptographically wise, they implement pretty much the exact same functionality but using different primitives. ChaCha20-Poly1305 makes sqleet probably a better choice for embedded systems and mobile devices with slow CPUs, but there is not much else to say about the cryptographic primitive choices. PBKDF2 iteration count and cipher are run-time configurable in SQLCipher, while sqleet supports only easy configuration of PBKDF2 iterations at compile time.

Practicalities

_ SQLCipher sqleet
Dependencies OpenSSL or LibTomCrypt or CommonCrypto None (self-contained)
Configurability Compile-time and run-time Compile-time (limited)
Popularity De facto standard Neverheard

SQLCipher offers no backward/forward source version compatibility, that is, upgrading SQLite3 version always requires major adjustments to the code of SQLCipher (there are typically one or two SQLCipher releases in a year; thus, SQLCipher users might have to wait up to 1 year for support of the latest SQLite3 version). In comparison, sqleet's backward/forward compatibility usually spans several SQLite3 versions, that is, the current version of sqleet source code most likely works with the upcoming SQLite3 versions without any modifications (just drop in the new SQLite3 amalgamation).

Additionally, the crypto of sqleet has been implemented from scratch and not validated, which simplifies compiling & linking (especially in embedded environments) but is a red flag to some people. The cryptographic primitives implemented in sqleet are reasonably resistant to side channel attacks (ChaCha20 and PBKDF2-HMAC-SHA256 by design, and the Poly1305 implementation is constant time).

https://github.com/resilar/sqleet/issues/12#issuecomment-366435774 For many users it is important however that the crypto provider is FIPS-validated - and this is the case for OpenSSL (FIPS validation). Whether this offers better security is a different question. Fact is, that decision makers in companies often rely on FIPS validation and the like.

utelle commented 6 years ago

I'd like to add a few comments:

  1. Preliminary note I'm not in favor of SQLCipher - in the contrary, I maintain a separate self-contained SQLite encryption extension (as part of my project wxSQLite3) myself since 2007. Nevertheless, I think it is important to make a fair, unbiased comparison as far as this is possible for a developer of a separate SQLite encryption extension.

  2. Lines of codes 3000 lines (SQLCipher) vs 1300 lines (sqleet) seems to indicate that sqleet is far more compact than SQLCipher. IMHO this comparison gives a false impression. There are reasons for the higher amount of code: support for 3 different crypto providers, support for run-time configuration via pragmas, and last but not least a lot of trace statements for debugging.

  3. Dependencies SQLCipher depends on an external crypto provider library. That's true, but it is not limited to OpenSSL. At the developer's discretion it is also possible to use LibTomCrypt or Apple's CommonCrypto instead of OpenSSL. And further crypto providers could be added - even your own implementation, since SQLCipher is open source, after all. For many users it is important however that the crypto provider is FIPS-validated - and this is the case for OpenSSL (FIPS validation). Whether this offers better security is a different question. Fact is, that decision makers in companies often rely on FIPS validation and the like.

  4. Run-time Configurability SQLCipher offers some options to configure it at run-time (via pragmas). However, several of them are only required to allow backward compatibility with earlier SQLCipher encryption scheme versions. sqleet will face a similar problem, when the encryption scheme is changed in a future version - i.e. in issue #3 you mention Argon2 as a replacement for PBKDF2. BTW, it wouldn't be a big deal to add run-time configurability (like changing the number of PBKDF2 iterations) for sqleet using SQLite's user-defined functions.

  5. Compatibility You claim that SQLCipher does not offer backward/forward version compatibility. This is simply not true. The version compatibility is more or less the same as for SQLite itself. Of course, if the encryption scheme changes - as was the case between SQLCipher version 1 and 2 -, databases encrypted with the older version have to be converted to the new scheme. However, this will be true for sqleet as well, as soon as you add Argon2 as an alternative or replacement for PBKDF2. A real problem of SQLCipher is that upgrading to a new SQLite version is a major effort, since several adjustments to individual SQLite source files have to be done, instead of just dropping in the latest SQLite amalgamation.

resilar commented 6 years ago
  1. Preliminary note ... Nevertheless, I think it is important to make a fair, unbiased comparison as far as this is possible for a developer of a separate SQLite encryption extension.

Agreed :)

  1. Lines of codes ... IMHO this comparison gives a false impression ...

In contrast, one could argue that the comparison is biased against sqleet because SQLCipher uses external crypto libraries instead of implementing its crypto. But yeah, LoC is always a sketchy metric.

  1. Dependencies ... At the developer's discretion it is also possible to use LibTomCrypt or Apple's CommonCrypto instead of OpenSSL. ...

Good point. I updated the issue description.

  1. Run-time Configurability ... BTW, it wouldn't be a big deal to add run-time configurability (like changing the number of PBKDF2 iterations) for sqleet using SQLite's user-defined functions.

This is not the route that I want to take with the project. I personally believe that vast configurability is (often) poor crypto design. The users (or even the developers) should not have to care about choosing safe ciphers and iteration counts. It is much better to make the decision for them (as a crypto tool/library author) and stick with one set of secure defaults. This eliminates insecure configurations, and sometimes compatibility issues as well.

  1. Compatibility ... You claim that SQLCipher does not offer backward/forward version compatibility. This is simply not true. ...

My bad, I did not express myself clear enough. I was talking about source version compatibility (which you described in the last sentence) and not binary compatibility of database files. I clarified the description a bit.

utelle commented 6 years ago

Lines of codes

... But yeah, LoC is always a sketchy metric.

Yes, indeed. So, why mention it at all? IMHO the main point is that SQLCipher has external dependencies, while sqleet has not. The latter is often an advantage.

Dependencies ... At the developer's discretion it is also possible to use LibTomCrypt or Apple's CommonCrypto instead of OpenSSL. ...

Good point. I updated the issue description.

Just to add one more alternative: it is also possible to build SQLCipher with LibreSSL.

Run-time Configurability ... BTW, it wouldn't be a big deal to add run-time configurability (like changing the number of PBKDF2 iterations) for sqleet using SQLite's user-defined functions.

This is not the route that I want to take with the project. I personally believe that vast configurability is (often) poor crypto design.

Well, look at the algorithms PBKDF2 or Argon2: both are configurable. Parameters can be chosen based on actual requirements. Values that are good enough for one environment/application might not be suitable for another environment/application.

The users (or even the developers) should not have to care about choosing safe ciphers and iteration counts.

I agree. Therefore it is important to select suitable default values. However, IMHO there is nothing wrong in allowing to adjust parameters, if users/developers have to face requirements you haven't foreseen on choosing your default values.

Yes, configurability will allow to select inappropriate parameter values. That is, giving advice how to select suitable values would be nice, of course.

It is much better to make the decision for them (as a crypto tool/library author) and stick with one set of secure defaults. This eliminates insecure configurations, and sometimes compatibility issues as well.

The set of secure defaults may be good and secure today ... but will it be secure tomorrow?

For example, SQLCipher used an iteration count of 4000 until version 2 and changed it to 64000 in version 3. Most likely a good decision ... but databases created with version 2 have to be converted to the new version 3 format. - If you would detect tomorrow that your choice of 12345 iterations is a really bad choice for some obscure reason, sqleet would face a similar problem.

The casual user/developer will not tamper with the default parameter values - the experienced user/developer may have reasons to choose different parameter values.