agens-no / EllipticCurveKeyPair

Sign, verify, encrypt and decrypt using the Secure Enclave
Other
708 stars 114 forks source link

Encrypting messages using CLI Open SSL #39

Open jvanzummeren opened 5 years ago

jvanzummeren commented 5 years ago

I'm playing around with both signing and ecrypting. The example project provides a way to verify signatures using openssl (by printing the statements in the debug log), which is working perfectly fine in the POC i'm working on.

I was wondering if you can assist in doing the same for encrypting messages using the public key from the device. Can openssl CLI encrypt messages which the device can decrypt using it's private key (which is stored in the secure enclave)?

Thanks in advance

Jim

hfossli commented 5 years ago

I am not an expert, but thankfully @dschuetz is!

Here’s an awesome writeup he did which will give you answers! :) https://darthnull.org/security/2018/05/31/secure-enclave-ecies/

Hopefully we get to merge instructions or point to this article in our library.

hfossli commented 5 years ago

I have given it an attempt at line by line porting @dschuetz's code. https://gist.github.com/hfossli/6763c2ceeba0f03ce45cc630bbbec7b0 Maybe you are able to finish it?

jvanzummeren commented 5 years ago

Thanks! Interesting article indeed! I had been experimenting with it as well but haven't figured out a complete solution yet either, i kind of got the feeling that it's not possible with the current openssl cli. Will let you know if i find any more information

dschuetz commented 5 years ago

First....using OpenSSL is fun, but damn it's a pain in the neck. Which is why I tend to do everything in Python now.

The first thing you're missing is the X963KDF function. In my blog post (https://darthnull.org/security/2018/05/31/secure-enclave-ecies/) I describe how that works, which is really simple:

sha-256( { shared_key } + counter + { shared_info}

The shared_key is the ECDH output, the shared_info is the ephemeral public key (in this case, Alice's public key), and the counter is a four-byte counter beginning at 1. Then we take only the 16 bytes of the output (I guess it's only 128-bit AES? I'm not seeing that well explained in my post...)

So:

$ echo "bc3e119513a70d348edcba6684493d462eb19240c8eeec2422820b7245829d9e 0000 0001 0413af8baa97bcf167edec2505e182185c2feebf278238fb1cba47a5df48dfc3dd74a9658e53a50531ac238b786ebeb13ef4c36ce6ff3f096b709f098b861f613c" | xxd -r -p| openssl sha256 -hex | cut -c 1-32

41006753ead5ec6e4c9a65675cbcaa95

Okay, now we've got the same key. But what about the encryption?

You're probably not going to like this: I think the OpenSSL command line simply doesn't support GCM. I've found a couple pages (and my notes from when I was playing with this last year) that say this outright, and another that says it does but doesn't generate (or validate) the tag, but clearly the output from the command line isn't "correct except for the tag" either.

Note that I'm using LibreSSL 2.6.5 (macOS Mojave). I just tried on an ubuntu box, with OPenSSL 1.0.2g, and get the error message "AEAD ciphers not supported by the enc utility."

If you try "openssl list-cipher-commands", you’ll see gcm isn't listed as available. I'm not sure why it's a recognized algorithm if it doesn't work with the enc command...maybe there are other commands that can use GCM where it does work. I forget. As I said, I long ago moved to doing it all in python...

I hope this helps, and sorry I could only answer half your question!

david.

Sent from my iPad

On Feb 28, 2019, at 5:55 AM, Jim van Zummeren notifications@github.com wrote:

Thanks! Interesting article indeed! I had been experimenting with it as well but haven't figured out a complete solution yet either, i kind of got the feeling that it's not possible with the current openssl cli. Will let you know if i find any more information

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

hfossli commented 5 years ago

Awesome! Thanks! Really helpful. Just one small step away.

The reason I want to be able to do this with openssl cli is just because it is so universal. It seems most experienced people are using python, c etc to do these things - totally understandable.