Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

Any interest in ECDSA? #129

Closed
jonasfj opened this issue Nov 6, 2014 · 15 comments
Closed

Any interest in ECDSA? #129

jonasfj opened this issue Nov 6, 2014 · 15 comments
Assignees
Labels
feature New functionality or improvement

Comments

@jonasfj
Copy link

jonasfj commented Nov 6, 2014

I've been building a larger collection of services using hawk to do authentication, with a single auth-service holding all credentials where other services fetch the credentials from. But I've found that as I want to let other services, less trusted, services use my auth-service (to manage credentials); that I would wish hawk had support for asymmetric algorithms.

ECDSA has high security with small 256 bit keys, and seems to be pretty fast; here is a demo I found using javascript:
http://kjur.github.io/jsrsasign/sample-ecdsa.html

So far I've used hawk and been very happy with it, because the key is relatively small 256 bit; which is easy to copy around, insert in environment variables, config files, etc.
But with 256bit ECDSA keys offering decent security, it's tempting to use that.

TL;DR
Would there be any interest in accepting a PR with support for ECDSA as algorithm?
(I fully understand if that is not the case)

@hueniverse
Copy link
Contributor

Supporting it as an algorithm isn't the question. It is the implicit endorsement. I would feel much better about it if we can get some crypto experts to chime in and compare that with the existing hmac based ciphers used today.

@hueniverse hueniverse self-assigned this Nov 6, 2014
@jonasfj
Copy link
Author

jonasfj commented Nov 6, 2014

Whilst I can hardly call myself and expert. I can reference some :)
The easiest available comparison of security levels is: http://www.keylength.com/en/3/
According to ECRYPT2 ECDSA in widespread use. It's not as battle hardened as RSA, DSA and Elgamal. There are some curves to avoid and as with any cryptographic algorithm lots of implementation pitfalls: timing attacks, poor randomness.

My biggest concern is that HMAC is easier to implement and hash functions are readily available everywhere. Finding ECDSA implementations used to be hard, but after it's use in bitcoin, ECDSA is more readily available. Though trustworthy implementations are still hard to find. This would be my main concern. Security properties of the actual algorithm is hard to reason about, certicom, NSA and cloudflare seems to be confident. But you can prove that nobody knows how to solve the DLP or find smoothness in elliptic curves.

But at the end of the day, we are comparing Apples and Bananas. HMAC-xxx is symmetric and hard to compare to asymmetric ciphers like ECDSA, which does have different properties, and offers a much better security architecture. One could easily use this to offer temporary credentials, so access can be delegated without replay attacks; I would do this as a hack on top of hawk.

ECDSA Pros: (Compared to HMAC)

  • Asymmetric (public/private keys, no secret key on the server)

ECDSA Cons: (Compared to HMAC)

  • More expensive to compute
  • Algorithm(s) are hard to implement
  • Limited availability of high quality implementations
  • Requires randomness (can be avoided for signing with RFC 6979)
  • Susceptible to timing attacks (limited relevance over network, or if implemented properly)
  • Client must send (or have on server) a public key to support response signatures
  • Potential patent issues (mostly expired though)

Yes, that's a lot of cons. In exchange for one big pro. Again, security-wise, I fear implementation issues more than the mathematical properties. Those can be questioned about HMAC too. Besides mathematical properties are rarely how things are attacked/broken, it's always implementation issues :)

Remark, we could support adding any algorithm as a plugin with something like hawk.registerAlgorithm(name, verifyFunc). This would solve the endorsement issue.

@hueniverse
Copy link
Contributor

I rather not make this extensible because that hurts interop. You can, of course, hack it into. A good start would be a solid node module - is there one?

@jonasfj
Copy link
Author

jonasfj commented Nov 7, 2014

The demo I referenced in initial post is from the jsrsasign library implemented in javascript. It has supposedly forked it ECDSA implementation from bitcoinjs. And the projects seems alive.

There are also others, and long-term we could definitely find an optional binary module using OpenSSL for better performance. I'm not sure that libraries such as jsrsasign are reviewed or has the same quality as OpenSSL (for example measures against timing attacks, etc). Like I said, my main concern is the quality of ECDSA implementations, I doubt many of them are reviewed. But there is a quite few around. And they seems to be tested against OpenSSL, so correctness is likely okay. Remaining pitfalls is likely limited to lack of randomness and timing attacks.

Note, there would be some changes as client would have to know the servers private key for response payload validation to work. Assuming one wants to support response payload validation. As distributing a servers public key does make payload validation more complicated.

Thoughts?

@hueniverse
Copy link
Contributor

What would it take to just use the OpenSSL implementation? Is it available via the node crypto interface? If we can support it without any special module on the server/node side, and only need the JS code for the browser side, I am much more open to it by making it an optional script import for those who want it.

@jonasfj
Copy link
Author

jonasfj commented Nov 7, 2014

There seems to be crypto.createSign('ecdsa-with-SHA1'), but I can't get ...-SHA256 working on my Wheezy with OpenSSL 1.0.1e, nor does SHA256 seem to exist on heroku (just saying). If it did exist it would likely be much faster.
We would have to do convert keys between hex or base64 and PEM. PEM encodes more meta-data that we likely want to stuff into hawk, to reduce size of keys. If we didn't care about key sizes, we might just as well use RSA.

I suspect open the built-in crypto library is mainly problematic because of old OpenSSL versions, or maybe I got the wrong name ecdsa-with-SHA256. Perhaps it's disabled at compile-time what do I know. I can't seem to find the solution.

Either way, I think we can find a binary module that can be employed. It seems secp256k1-node wraps a binary module for bitcoin that is heavily optimized. If the module can't install, or we're in a browser, we can easily fall back to elliptic. But yes, using the node crypto would have been awesome.

@hueniverse
Copy link
Contributor

Did you try on node 0.12?

@jonasfj
Copy link
Author

jonasfj commented Nov 8, 2014

I'll make some tests and benchmarks of the libs... Also to make sure they are properly compatible. To be honest I'm also concerned with python compatibility. But I'll run some tests and get some numbers..

@jonasfj
Copy link
Author

jonasfj commented Nov 8, 2014

So I while rooting around I discovered gryphon a hawk like thing (if not earlier fork) that uses ECDSA over the Ed25519 curve. It seems there is a lot of work on this, to make something very fast and easy to use.
See libsodium or tweetnacl.cr.yp.to...

I've tested compatibility between a few of the libraries for node. As well as performance. The javascript based ones aren't performing that well, probably find for browsers and quickly deployed clients. Note js-NaCl is a C library compiled to JS taking up 32 MB if instantiated. node-sodium on the other hand seems very nice, there is a few metods I would add bindings for, but that seems relatively trivial.

Check out the preliminary results: https://gist.github.com/jonasfj/af453cc2c569312ac59f#file-results-txt

@jonasfj
Copy link
Author

jonasfj commented Nov 11, 2014

So I updated the tests/results two days ago... after adding fromSeed support to libsodium.

This evening I ported node-sodium to node 0.11 using nan, so we're likely to have 0.12 support when it comes out (or quickly be able to add it; but the idea is that nan maintainers will ensure compatibility as best possible).

So I think most of the blockers are out of the way, I've also located multiple python bindings for libsodium and tweetnacl, so python support should be possible (this is important to me).

I think conclusion from this discovery is that:

  • ECDSA (over any curve) would likely require a binary module (to ensure performance)
    In browser there is plenty of pure JS implementations, but they are slow, not noticeable in
    a client-side application. But too slow for server side use.
  • Node 0.10, 0.11/0.12 and python support is not an issue
  • In terms of security properties ECDSA is rather in-comparable to HMAC-SHA256..
  • ECDSA is in wide-spread use (not as much as RSA, HMAC), but it's a corner stone of bitcoin
    and also used in SSL certificates.

What is your thoughts? I fully understand if binary dependencies are too heavy. Forking would be easier, but I'm willing to put in a little bit more effort if you're not ready to discard the idea of merging this :)

Remark, I'm not entirely sure how easy it is to make dependencies optional without people forgetting to add them. But that is something we could do.

@hueniverse
Copy link
Contributor

I think the right approach is to make hawk a bit more extensible so you can use it without forcing the deps on others and allowing people to try new things out. I think the next step is to do the work and add support in a PR. Once that is done I can figure out how to modulerize it.

@hueniverse
Copy link
Contributor

cc @seanmonstar

@Kagami
Copy link

Kagami commented Jan 13, 2015

Hi. Sorry for the interruption. I see you guys here discussing ECC implementations in node (thanks for the links, btw).
I'm writting simple isomorphic wrapper around elliptic (Browser) and secp256k1-node (Node) to work with K-256 curve. You may take a look.

At first I was trying to use native Node crypto module and WebCryptoAPI but:

@jonasfj
Copy link
Author

jonasfj commented Jan 16, 2015

ECDSA with secp256-k1 (as used by bitcoin) or EdDSA over Ed25519 as done by libsodium/NaCl, certainly seems like good cryptographic schemes for this purpose.

I started fooling around with hawk, trying to see if it would fit in nicely. But:

  • hawk is clearly architected for symmetric schemes,
  • features such as response signatures doesn't fit well with asymmetric schemes, and
  • considering the amount of changes involved it's unrealistic to expect other hawk implementations to catch up.

So I'm increasingly leaning towards not implementing this in hawk.


Slightly off-topic, but an alternative remedy to the issue with a single entity storing credentials and distributing them to multiple services can be solved with symmetric algorithms, by repeated application of HMAC the way AWS does it in their signature format version 4.

Basically, when authentication against example.com, you give hawk the key HMAC(secret, 'example.com'), that way the service running at example.com doesn't need to know secret. And the server storing credentials (hence, knows secret) just shares the value HMAC(secret, 'example.com') with example.com.


Anyways, considering that it would be hard to hawk implementions in python, ruby, php, etc. to implement an asymmetric scheme maybe we shouldn't try to stuff this into hawk.

@Marsup Marsup added feature New functionality or improvement and removed request labels Sep 21, 2019
@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature New functionality or improvement
Projects
None yet
Development

No branches or pull requests

4 participants