ntrepid8 / ex_crypto

Wrapper around the Erlang crypto module for Elixir.
MIT License
144 stars 48 forks source link

Help handling aes256cbc #4

Closed bglusman closed 6 years ago

bglusman commented 7 years ago

I'm struggling currently to get clean, easy encryption interoperability between ruby and elixir, which looks easy on paper as both use OpenSSL under the hood, but think elixir community could use some better abstractions around Erlang crypto, which looks like exactly what this library is out to offer!

I got a simple zero IV working using this code: https://gist.github.com/bglusman/7e1df9efad80845977b60d44d335f3df

But it's brittle and awkward and I thought perhaps we can include some elixir version here that will: a) help avoid invalid IV values b) perhaps provide easy options to decrypt existing widely used options from ruby and/or other standard libraries

In ruby we're using attr_encrypted for DB encryption, though still currently stuck on 1.4 until we can find time to use explicit IV's instead of "single_iv_and_salt" which I think corresponds to using pkcs5_keyivgen in ruby OpenSSL, but I'm not 100% sure. Being able to support both that and explicit IV's would be nice, but I also wasted a lot of time not realizing that all IV's had to be 128 bits which a good error message would help, and whatever I've screwed up now that erlang just says "** (ErlangError) erlang error: :notsup" in response to should also hopefully be able to have a more illuminating/useful error message as well :-)

Folks in the #security channel on elixir slack may be up for helping, they helped me past the 128 bit issue, I'll post this issue there as well.

ntrepid8 commented 7 years ago

I was indeed trying to help a bit with making abstractions easier. One issue I've run into is that often there are not hard and fast rules about how the different bits should be packaged up and then unpackaged for decryption. In this module I've simply tacked the IV, cipher-text, cipher-tag together in the 'payload'.

For interop between different languages to be made easy, I wonder if it wouldn't make sense to take something like MessagePack and build a crypto layer around it with libraries for multiple languages.

One of the reasons why I've chosen GCM mode in this library was to minimize the possibility of "doing it wrong" which is always a problem with crypto. If you don't use it all the time, it's kind of difficult to know if you are even doing it correctly, even when everything seems to work.

bglusman commented 7 years ago

I've never used MessagePack, but at a guess, queues and databases likes Redis, SQS and ElasticSearch would in my guestimation be more common than messagepack for interop... plain JSON seems more useful if you need a message format, but for my purposes I'd prefer to just have interoperable crypto on the raw encrypted values rather than assume anything about the context you'll receive the values in, though I can see for supporting multiple languages/creating something of a reference implementation it might be worthwhile/necessary.

I've heard good things about GCM, though it only got added to SSL in, like, 1.02 or something, which is pretty recently, and not all languages support for it seems to be at the same level. I think having encryption be interoperable, though perhaps with detection and warning of some bad practices, would help people out more than trying to prescribe a single way to do things, though having a happy/encouraged path is always nice. If I manage to make a nice abstraction for my use case, maybe I can do it in a fork of this and PR, or if you have any ideas or preferences for how to do it, or want to help, please let me know :-)

bglusman commented 7 years ago

@ntrepid8 just saw your comment on my gist, replied there, and my problem seems fixed so will start on implementing this in a fork.... (unsure if @ in a gist pings so @'ing here again)

ntrepid8 commented 6 years ago

I'm closing this because I'm pretty sure it's resolved by PR #5.