Recommended high-level cryptography library?

Can anyone recommend a high-level cryptography library for Haskell, ideally with sensible defaults, so that a beginner could get started and avoid making serious mistakes?

Cryptonite seems widely used but explicitly warns in its README that, “If you have no idea what you’re doing, please do not use this directly. Instead, rely on higher level protocols or implementations.”

Haskell-crypto seems good, but is listed as “experimental” which is dissuading.

The use-case is for symmetric encryption of database values. I am both a beginner in Haskell and cryptography, hence the need for a high-level library that would help me avoid making serious mistakes.

If you like unverified implementations and don’t mind a GCed language with no specification for the RTS to handle your bit secrets, then cryptonite is fine.

Otherwise you’re left with C bindings (usually individual packages). And there won’t be much high level around it.

2 Likes

For encryption of values in database tables, I suggest using the builtins in the database itself as the cleanest method. For example, postgres has the pgcrypto module: PostgreSQL: Documentation: 14: F.26. pgcrypto

If you really do want to work with crypto outside of db builtins, a reliable set of c functions to bind to comes from the sodium library, and you can find a decent set of bindings to it here: saltine: Cryptography that's easy to digest (NaCl/libsodium bindings).

4 Likes

Thank you very much for the advice!

@sclv Using pgcyrpto does indeed sound clean. I came across this StackExchange post [1] in which a poster warns that the key can be leaked in logs. Is this still a concern? If so, how would you advise avoiding that vulnerability?

[1] functions - How to use aes-encryption in PostgreSQL? - Database Administrators Stack Exchange

Well you would need to keep your logs secure, and scrub them. But also bear in mind that in general and barring doing silly things with your logs, if someone has access to your logs, they have access to your server, which means they will have access to your key one way or another. Two way encryption of data in a database is often not the most secure way to solve many problems in general, and can often be replaced by hashing and salting, or pushing crypto to the client layer, or one of many other solutions, depending on what exactly you hope to accomplish.

Thanks again for the advice. I will be storing accounting data (transactions and balances) in my PostgreSQL database which needs to be viewed by the client, so I presume hashing would not be appropriate. Maybe I should not even be attempting to store such accounting data in PostgreSQL?

Edit: I will not be storing any bank account or credit card numbers, however.

At this point I have some ideas, but honestly I’m not expert enough to know what current best practices are in a security architecture for this sort of app. My only advice would be that this is a problem that people have thought about and come up with reasonable answers for, if you go looking, and that all good security architecture starts with a threat model of what data you want to secure from what actors assuming said bad actors are equipped with what capabilities.

4 Likes

This was the goal of the Haskell cryptography group, though I confess I haven’t been following its progress lately.

1 Like

@sclv Thank you for the honest and helpful advice. I will research security architecture some more then.