Generating RSA key pair in Elixir

1,365 views
Skip to first unread message

Adrien Anselme

unread,
Jan 8, 2015, 2:01:42 PM1/8/15
to elixir-l...@googlegroups.com
Hi,

What is the best way to generate an RSA public/private key pair in Elixir?

I used to use cutkey to generate an {E, N, D} tuple that can be used directly with the other functions from Erlang library, but it seems a bit deprecated now (No new releases in a while).
I also looked into :crypto.generate_key/2 but don't understand from the doc what are the expected arguments. Apparently :rsa for argument 1, but argument 2?
I presume I could also launch openssl command line tools.

Anyone has some experience with this?

Paulo Almeida

unread,
Jan 9, 2015, 4:16:58 PM1/9/15
to elixir-l...@googlegroups.com
Hello,

There is no built-in function to generate RSA key pairs. The crypto module itself is mostly bindings to OpenSSL, so I guess there must be a valid reason why RSA key generation is not exposed. Maybe the fact that it can be slow (explains why cutkey implementation uses a port driver instead of nifs).
The generate function in crypto only generates Diffie-Hellman and ECDH key pairs.

Like you suggest, one option is to launch openssl to generate a PEM file and then read it:

iex(1)> :os.cmd 'openssl genrsa -out mykey.pem 2048'
iex(2)> {:RSAPrivateKey, :'two-prime', n , e, d, _p, _q, _e1, _e2, _c, _other} = File.read!("mykey.pem") |> :public_key.pem_decode |> List.first |> :public_key.pem_entry_decode
iex(3)> plain_text = "please don't read this"
iex(4)> priv_key = [:crypto.mpint(e), :crypto.mpint(n), :crypto.mpint(d)]
iex(5)> pub_key = [:crypto.mpint(e), :crypto.mpint(n)]
iex(6)> sekrit = :crypto.rsa_private_encrypt(plain_text, priv_key, :rsa_pkcs1_padding)
iex(7)> plain_text == :crypto.rsa_public_decrypt(sekrit, pub_key, :rsa_pkcs1_padding)

References:

ECDH (Elliptic Curves) on the other hand is well supported by the :crypto library, in case you have to option of using that instead of RSA (a 256 bit ECDH key is supposedly as secure as a 3072 bit RSA key).

Regards,

Paulo

Adrien Anselme

unread,
Jan 11, 2015, 1:53:57 PM1/11/15
to elixir-l...@googlegroups.com
Thanks Paulo, this works great.

Since it has to work with legacy code that expects RSA, I'll stick with it for the moment, but I'll plan to move to ECDH when time permits.
For the record, this is what I ended up doing:

  def generate_rsa() do
    {pem, 0} = System.cmd "openssl", ["genrsa","2048"]
    {:RSAPrivateKey, :'two-prime', n , e, d, _p, _q, _e1, _e2, _c, _other} = pem
    |> :public_key.pem_decode |> List.first |> :public_key.pem_entry_decode
    {e, n, d}
  end


Cheers,
Adrien


--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/PW2S0iUln18/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages