Jsondb / jsondb-core

JsonDB a pure java database that stores its data as Json Files

Home Page:http://www.jsondb.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Insecure default cipher

yawkat opened this issue · comments

The default cipher implementation at https://github.com/Jsondb/jsondb-core/blob/c49654d1eee2ace4d5ca5be19730652a966ce7f4/src/main/java/io/jsondb/crypto/DefaultAESCBCCipher.java is vulnerable to various attacks.

The cipher construction used is AES-128/192/256 in CBC mode with PKCS5 padding with the key as the IV and no authentication.

  • Lack of authentication leads to various interactive attacks. PKCS5+CBC makes these attacks fairly simple.
  • Using the key as the IV can be used to reveal the key, as CBC does not protect the confidentiality of the IV. For example, given a limited decryption oracle, an attacker could decrypt two identical blocks A||A. The decryption oracle in this mode will yield (Dec_K(A)^K) || (Dec_K(A)^A), which can be used to extract K.
  • Using the same IV repeatedly leads to distinguisher attacks.

All in all, this set of algorithms provides IND-EAV security at most. While the documentation does state that "CBC may not be the most secure mode", this is a severe understatement. Offering this set of algorithms as the only default, and even offering it at all, will lead to insecure storage of secrets.

Thanks for finding this, how pathetic of me I never ever gave a thought to this aspect. I will fix this asap with some other things I have in mind.

@yawkat do you have any suggestions for the chiper to use?

The "ideal" solution would be something like NaCl's crypto_secretbox. However, this would entail adding external libraries, which is probably overkill for this project.

Using only the Java standard library, our suggestion would be AES-GCM. A quick google shows this example: https://gist.github.com/praseodym/f2499b3e14d872fe5b4a which seems sane. The AAD part is not relevant here I believe, since you have no associated plaintext data. The nonce for the operation must be random - GCM is not nonce-reuse resistant. Also note that SecureRandom.getInstanceStrong, as used in the example, may block. Another SecureRandom provider such as SHA1PRNG may be better if you wish to avoid this, and should not seriously undermine security.

The random nonce can simply be prefixed to the final encrypted message. It does not need to be secret.

This has been fixed by @rzwitserloot