Closed cromefire closed 2 years ago
We do not currently have any support for ECIES. If we want to include it we need to answer a few questions:
A start at answering them:
ECIES is a pretty generate paradigm for generation an ephemeral ECDH key, doing a kex with someone's public key, runnign the result through a KDF, and then using that as a symmetric key to actually encrypt that data.
We have all the pieces to do that, the question is, is there a common encoding we can use, or would implementing ECIES mean defining our own?
Use case: I have a node, which holds the private key, a web server and a client. The client inputs data, which should be encrypted and sent to the web server. The node with the private key gets the data from the server (manual, maybe once a week or less often) and decrypts it (preferred python).
Important: The server has tls, but the data may not be readable by the server at any time.
Serialization is not a problem for me, I can handle that manually
If you need some inspiration / information / (kind of) reference implementation, I plan to use bitpay/bitcore-ecies for my front-end and they should have had the same problems and solved them.
An example of use of ECIES is in Google Pay:
Google uses the Elliptic Curve Integrated Encryption Scheme (ECIES) to secure the payment method token
https://developers.google.com/payments/payment-data-cryptography
It is also supported by several other crypto libraries, such as BouncyCastle and Tink for Java, and Crypto++ for C++.
Regarding @alex question:
We have all the pieces to do that, the question is, is there a common encoding we can use, or would implementing ECIES mean defining our own?
There are many variants of ECIES, since there have been many standards (ANSI X9.63, ISO/IEC 18033-2, IEEE P1363A). The ISO/IEC 18033-2 variant is probably the most complete.
Joining the request for ECIES support.
:+1: for ISO/IEC 18033-2 variant of ECIES support.
As it is a (if not the only) good way of implementing easy asymmetric encryption with ecc this could provide a better alternative to simple rsa.
I've seen a bunch of examples of ISO and ANSI being used in the wild so I'm convinced of the notability. I haven't looked for test vectors but the ability to obtain a decent set of those is probably the next gate for adding support.
ISO/IEC 18033-2 defines some test vectors for ECIES-KEM in Appendix C.2.1, although all of them using a KDF instantiated with SHA-1 as the internal hash function. That's a start.
I'm afraid that ANSI X9.63 2011 doesn't have test vectors for their version of ECIES-KEM.
Hello everyone, has been ECIES scheme implemented? I need it for an ETSI standard implementation.
I resolved this by creating my method consisting of:
This works anywhere, where scrypt, ECDH and miscreant (or another AES-RIV implementation) works, I am able to use it in Python and the browser.
But as I'm not a security expert I cannot recommended this, If you can't verify yourself that this is secure. And it's of course not standardized.
@cromefire The use of Scrypt is probably overkill there, since it's designed for low-entropy inputs like passwords. In your case, an ECDH derived secret can be expanded securely with a Key Derivation Function (KDF) like HKDF, in a much more performant way.
@reaperhulk @alex What do you guys need to advance in this issue? In this comment (https://github.com/pyca/cryptography/issues/4093#issuecomment-366221249) I mention potential instantiations of ECIES, although ISO/IEC 18033-2 seems like the most relevant. As an example, see what they use in this spec for Google Pay:
Parameter Definition Key encapsulation method ECIES-KEM, as defined in ISO 18033-2. Elliptic curve: NIST P-256 (also known in OpenSSL as prime256v1). CheckMode, OldCofactorMode, SingleHashMode, and CofactorMode are 0. Point format is uncompressed. Key derivation function HMAC-based with SHA-256 (HKDFwithSHA256). Salt must not be provided.Information must be Google-encoded in ASCII for protocol version ECv2. 256 bits must be derived for the AES256 key and another 256 bits must be derived for the HMAC_SHA256 key. Symmetric encryption algorithm DEM2, as defined in ISO 18033-2. Encryption algorithm: AES-256-CTR with zero IV and not padded. MAC algorithm HMAC_SHA256 using a 256-bit key as derived from the key derivation function.
Would you be open to consider a PR implementing something like this? We at @nucypher can certainly collaborate here.
@cygnusv Does this spec (so ISO 18033-2) of ECIES allow other curves than P256?
@cygnusv The only thing holding this up is resources, so if you'd like to do the research around potential options and propose a concrete implementation we'd be happy to discuss and review it!
I think the first step here is deciding on a particular ECIES implementation. If Google Play is using ISO 18033-2 then that's an option. Tink also appears to have an ECIES-KEM, which may be an even better candidate (although perhaps they're using the same ISO standard).
Looks like there are quite a few specific choices we'll have to either make APIs for or be opinionated about (if we want to make this a recipe). It is typically easier to build an API in hazmat and then make opinionated choices for a recipe later though.
@reaperhulk Awesome :) I'll work on this and submit a PR soon, then.
@cromefire ISO 18033-2 works for a big family of curves, not only P256. There's even the possibility of using it with curves with cofactor different than 1 (although not sure why one would want to do that).
It's probably worth looking at cryptopp's implementation and their changes to make their implementation compatible with Bouncy Castles implementation. https://cryptopp.com/wiki/Elliptic_Curve_Integrated_Encryption_Scheme
a big family of curves
@cygnusv I'm asking especially for X25519 and X448 (so the not NSA curves)
I resolved this by creating my method consisting of:
- The other one's public key
- Generation a new key pair
- ECDH
- Discarding the private key
- Scrypt
- AES-RIV for the encryption of the data (using miscreant)
- Sending encrypted data, IV (or however it is called in AES-RIV) and the public key
This works anywhere, where scrypt, ECDH and miscreant (or another AES-RIV implementation) works, I am able to use it in Python and the browser.
But as I'm not a security expert I cannot recommended this, If you can't verify yourself that this is secure. And it's of course not standardized.
@cromefire Do you have a gist/code sample for this?
@Bertje here you are: https://gist.github.com/cromefire/02f89c62829d601264747dcee82f424d
I hope it's correct, because I had to modify a bunch of things in the browser
In my search for easy-to-use, proven-to-be-secure crypto modules, I bounced into the crypto library which is established by well-known, renowned professors [1][2][3]; the NaCL library. There is a Python version of this as well; PyNaCl. Their SealedBox approach, using ephemeral keys, is what I'm experimenting with now. There are also other implementations of this NaCL library, e.g. ,for C, C++ and more.
[1] "The core NaCl development team consists of Daniel J. Bernstein (University of Illinois at Chicago and Technische Universiteit Eindhoven), Tanja Lange (Technische Universiteit Eindhoven), and Peter Schwabe (Radboud Universiteit Nijmegen)." [2] They are also the brainpower behind the ECC save curves project: https://safecurves.cr.yp.to/. Especially as none of the curves supported by pyca are "safe-to-use" according to this project, having a look at the NaCl is worth the effort I'd say. Why aren't those safe curves supported anyway? [3] Fun fact: they lectured @ my infosec Masters
Why aren't those safe curves supported anyway?
See openssl
HPKE is now standardised as RFC9180 and (to my mind) is a more sanely constructed and modern ECIES than the multi-dimensional ECIES toolkits standardised in X9.63, P1363, etc. https://github.com/ctz/hpke-py is an implementation of much of it atop cryptography.io.
Alex and I agree that hpke-py looks like exactly the ECIES people should generally use. I'm going to close this (thanks for writing that @ctz!), but if this doesn't handle everyone's use cases please feel free to comment again.
At this point I cannot see support for ECIES in cryptography, but I think it is worth thinking about supporting it as it is (correct me if I'm wrong) the only way for asymmetric cryptography in Ecc (in a way, that does not require direct communication). I read that it's really easy to implement, if you have the primitives, but I'm not a crypto expert so I request that it is either implemented (preferred) or explained in the docs. If this is already implemented I request better documentation.