How to use Elliptic Curves Diffie-Hellman with SJCL in JS and OpenSSL in Ruby

杀马特。学长 韩版系。学妹 提交于 2019-12-06 15:31:49
jww

#Server EC: code taken and modified from https://www.ruby-forum.com/topic/3966195 ec = OpenSSL::PKey::EC.new(group) ec.generate_key ...

Usually, we just call EC_KEY_new_by_curve_name with the NID of a well known curve. The NIDs would include:

  • NID_secp160k1
  • NID_secp192k1
  • NID_secp224k1
  • NID_secp256k1
  • NID_secp384r1
  • NID_secp521r1
  • other primary field curves
  • other binary field curves

I think the complete list of them is available in the OpenSSL sources, obj_mac.h:

#define SN_secp112r1        "secp112r1"
#define NID_secp112r1       704
#define OBJ_secp112r1       OBJ_secg_ellipticCurve,6L

#define SN_secp112r2        "secp112r2"
#define NID_secp112r2       705
#define OBJ_secp112r2       OBJ_secg_ellipticCurve,7L

#define SN_secp128r1        "secp128r1"
#define NID_secp128r1       706
#define OBJ_secp128r1       OBJ_secg_ellipticCurve,28L

#define SN_secp128r2        "secp128r2"
#define NID_secp128r2       707
#define OBJ_secp128r2       OBJ_secg_ellipticCurve,29L

#define SN_secp160k1        "secp160k1"
#define NID_secp160k1       708
#define OBJ_secp160k1       OBJ_secg_ellipticCurve,9L

#define SN_secp160r1        "secp160r1"
#define NID_secp160r1       709
#define OBJ_secp160r1       OBJ_secg_ellipticCurve,8L

#define SN_secp160r2        "secp160r2"
#define NID_secp160r2       710
#define OBJ_secp160r2       OBJ_secg_ellipticCurve,30L

#define SN_secp192k1        "secp192k1"
#define NID_secp192k1       711
#define OBJ_secp192k1       OBJ_secg_ellipticCurve,31L

#define SN_secp224k1        "secp224k1"
#define NID_secp224k1       712
#define OBJ_secp224k1       OBJ_secg_ellipticCurve,32L

#define SN_secp224r1        "secp224r1"
#define NID_secp224r1       713
#define OBJ_secp224r1       OBJ_secg_ellipticCurve,33L

#define SN_secp256k1        "secp256k1"
#define NID_secp256k1       714
#define OBJ_secp256k1       OBJ_secg_ellipticCurve,10L

#define SN_secp384r1        "secp384r1"
#define NID_secp384r1       715
#define OBJ_secp384r1       OBJ_secg_ellipticCurve,34L

#define SN_secp521r1        "secp521r1"
#define NID_secp521r1       716
#define OBJ_secp521r1       OBJ_secg_ellipticCurve,35L

#define SN_sect113r1        "sect113r1"
#define NID_sect113r1       717
#define OBJ_sect113r1       OBJ_secg_ellipticCurve,4L

#define SN_sect113r2        "sect113r2"
#define NID_sect113r2       718
#define OBJ_sect113r2       OBJ_secg_ellipticCurve,5L

#define SN_sect131r1        "sect131r1"
#define NID_sect131r1       719
#define OBJ_sect131r1       OBJ_secg_ellipticCurve,22L

#define SN_sect131r2        "sect131r2"
#define NID_sect131r2       720
#define OBJ_sect131r2       OBJ_secg_ellipticCurve,23L

#define SN_sect163k1        "sect163k1"
#define NID_sect163k1       721
#define OBJ_sect163k1       OBJ_secg_ellipticCurve,1L

#define SN_sect163r1        "sect163r1"
#define NID_sect163r1       722
#define OBJ_sect163r1       OBJ_secg_ellipticCurve,2L

#define SN_sect163r2        "sect163r2"
#define NID_sect163r2       723
#define OBJ_sect163r2       OBJ_secg_ellipticCurve,15L

#define SN_sect193r1        "sect193r1"
#define NID_sect193r1       724
#define OBJ_sect193r1       OBJ_secg_ellipticCurve,24L

#define SN_sect193r2        "sect193r2"
#define NID_sect193r2       725
#define OBJ_sect193r2       OBJ_secg_ellipticCurve,25L

#define SN_sect233k1        "sect233k1"
#define NID_sect233k1       726
#define OBJ_sect233k1       OBJ_secg_ellipticCurve,26L

#define SN_sect233r1        "sect233r1"
#define NID_sect233r1       727
#define OBJ_sect233r1       OBJ_secg_ellipticCurve,27L

#define SN_sect239k1        "sect239k1"
#define NID_sect239k1       728
#define OBJ_sect239k1       OBJ_secg_ellipticCurve,3L

#define SN_sect283k1        "sect283k1"
#define NID_sect283k1       729
#define OBJ_sect283k1       OBJ_secg_ellipticCurve,16L

#define SN_sect283r1        "sect283r1"
#define NID_sect283r1       730
#define OBJ_sect283r1       OBJ_secg_ellipticCurve,17L

#define SN_sect409k1        "sect409k1"
#define NID_sect409k1       731
#define OBJ_sect409k1       OBJ_secg_ellipticCurve,36L

#define SN_sect409r1        "sect409r1"
#define NID_sect409r1       732
#define OBJ_sect409r1       OBJ_secg_ellipticCurve,37L

#define SN_sect571k1        "sect571k1"
#define NID_sect571k1       733
#define OBJ_sect571k1       OBJ_secg_ellipticCurve,38L

#define SN_sect571r1        "sect571r1"
#define NID_sect571r1       734
#define OBJ_sect571r1       OBJ_secg_ellipticCurve,39L
...

#Compute Shared Key shared_key = ec.dh_compute_key(pub.public_key)

There's an example of ECDH on the OpenSSL wiki. I believe Matt Caswell provided it. You can find it at Elliptic Curve Diffie Hellman.

I think the OpenSSL wiki example was also copy/pasted once here: ECDH secrets generated by BouncyCastle Java API and by OpenSSL are different.

I don't know SJCL or Ruby, so I can't help you.


sjcl.ecc.curves['c384'] <- NIST

I believe you would want NID_secp384r1 for this, but I don't know Ruby so take it at face value. For a list of named curves to NIDs, see OpenSSL: openssl/ CHANGES openssl/apps/ ecparam.c openssl/crypto....


If you are going to save the key to disk and possibly use it later in a certificate (for example, ECDSA signing), then you will want to set the OPENSSL_EC_NAMED_CURVE flag. The flag simply saves the group parameters by name (for example, ASN1 OID: prime256v1) rather than listing all the domain parameters in ASN1 objects (field type, primary or binary field, base point, etc).

You do that with:

EC_KEY_set_asn1_flag(key, OPENSSL_EC_NAMED_CURVE);

If you don't set the flag, then you will encounter "no shared ciphers" error when negotiating suites. Here are the symptoms on the client and server:

  • Client (s_client):

    • 139925962778272:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1256:SSL alert number 40
    • 139925962778272:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
  • Server (s_server):

    • 140339533272744:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1353:
Jay-Ar Polidario

I've finally solved this problem! :)

I used a different Javascript library. If you're looking on solving similar problem like this, please refer to the other question of mine (link)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!