pyca / cryptography

cryptography is a package designed to expose cryptographic primitives and recipes to Python developers.
https://cryptography.io
Other
6.44k stars 1.48k forks source link

[Feature Request] Add support for ECIES #4093

Closed cromefire closed 2 years ago

cromefire commented 6 years ago

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.

reaperhulk commented 6 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:

alex commented 6 years ago

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?

cromefire commented 6 years ago

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

cromefire commented 6 years ago

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.

cygnusv commented 6 years ago

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++.

cygnusv commented 6 years ago

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.

elichai commented 6 years ago

Joining the request for ECIES support.

tuxxy commented 6 years ago

:+1: for ISO/IEC 18033-2 variant of ECIES support.

cromefire commented 6 years ago

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.

reaperhulk commented 6 years ago

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.

cygnusv commented 6 years ago

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.

dima91 commented 5 years ago

Hello everyone, has been ECIES scheme implemented? I need it for an ETSI standard implementation.

cromefire commented 5 years ago

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.

cygnusv commented 5 years ago

@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.

cromefire commented 5 years ago

@cygnusv Does this spec (so ISO 18033-2) of ECIES allow other curves than P256?

reaperhulk commented 5 years ago

@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.

cygnusv commented 5 years ago

@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).

rectalogic commented 5 years ago

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

cromefire commented 5 years ago

a big family of curves

@cygnusv I'm asking especially for X25519 and X448 (so the not NSA curves)

Bertje commented 4 years ago

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?

cromefire commented 4 years ago

@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

Bertje commented 4 years ago

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

cromefire commented 4 years ago

Why aren't those safe curves supported anyway?

See openssl

ctz commented 2 years ago

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.

reaperhulk commented 2 years ago

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.