SQLiteDatabase.EncryptionKey key derivation

AES-128 always wants 128-bit keys, and AES-256 always wants 256-bit keys. The examples just give db.EncryptionKey = "horse+20$" so what is the technique being used to produce a valid AES key? Pad with nulls? Repeat? If the key is too long, does it truncate?

https://www.sqlite.org/see/doc/trunk/www/readme.wiki

SEE says that the default is to complete with repeats until the key limit and truncate at 16 bytes for 128, 32 for 256.

Alternatively, use Crypto.PBKDF2 (or similar) with SHA-256 or -512 to stretch it.

If you pre-hash a key, only the first 16 bytes of that hash will be used for the default AES-128, or 32 bytes if using the AES-256 mode.

Thank you, that’s precisely what I was looking for.

1 Like

I just tested it.

Created a database with

db.EncryptionKey = "1234567890123456abc"

Tried to open with

db.EncryptionKey = "123456789012345"

And it failed. Then tried again truncating at 16 bytes as

db.EncryptionKey = "1234567890123456"

And it worked. So the “abc” was just discarded.

Note from the docs:

2018r1 and later defaults to AES-128, but AES-256 can also be used by including the prefix “aes256:” before the rest of the encryption key.

Yes. My technique is “just” EncryptionKey = “aes256:” + Crypto.Sha3_256(Key) so I was really just curious if this was a good idea. If it were already hashing, it’d be pointless. Repeat + truncate is fine too.

There’s a potential problem here, the lib has a problem with nulls in this string, so some workaround is needed as

"aes256:"+Crypto.SHA3_256("key").StringValue(0,32).ReplaceAllBytes(ChrB(0), ChrB(1))

Thanks for the heads up.

1 Like