Elixir/Erlang equivalent of Ruby OpenSSL

Hi everyone,

I like to know how to how to implement the following Ruby code in Elixir. I guess that I need to look in the Erlang crypto reference but I can’t figure out how to translate the code to Elixir/Erlang.

group = OpenSSL::PKey::EC::Group.new("prime256v1")
key = OpenSSL::PKey::EC.new(group)
pk_bn = OpenSSL::BN.new(pk_bytes, 2)
pk = OpenSSL::PKey::EC::Point.new(group, pk_bn)

I already found how to generate the key.

:crypto.generate_key(:ecdh, :prime256v1)

But how to create the public key bignum (pk_bn) and the public key (pk)?

ps the pk_bytes variable is passed in as a parameter.

Sorry I don’t know exactly what that Ruby code is doing, but probably the app you are looking for is :public_key:


1 Like

Hi Jeremujh,

If I look at the source from the Ruby documentation. It looks like the OpenSSL function BN_bn2bin docs is called from Ruby. I’m not sure what the equivalent in Erlang is but I will have a look at the link you suggested.

Does the following link give you a start?

I know it’s not directly related but I had to make an Elixir app that can parse Rails authentication cookies a while ago and this helped me.

EDIT: oops, gave wrong link the first time.

I don’t think you will find the same crypto primitives to do what you want directly from erlang/elixir. The ruby OpenSSL seems to be almost a one-to-one wrapper with OpenSSL whereas the erlang crypto NIF provides a higher abstraction.

The question is what you are trying to achieve? If the code was a function, what is the expected in and out parameters? From the look of the code above you have an incoming parameter pk_bytes (what is pk_bytes?). What do you want to return?

1 Like

dimitarvp, thanks I will have a look at the sources you provided.

Hi cmkarlsson,

Indeed the Ruby OpenSSL classes are a wrapper. But I guess that the same goal can be achieved with Erlang somehow.

I’m writing a WebAuthn package on Github inspired by webauthn-ruby. You can find the original sources of this method here.

The pk_bytes variable (this must be public_key_bytes actually) is a public key in bytes. The function verifies data from an authenticator using this public key. I found this Erlang code in the documentation crypto:verify(rsa, sha, <<"The message">>, Signature, PublicKey) I guess this does what I need as an output for this function.

So if I understand correctly, pk_bytes is a raw ECC public key without a curve identity, just a point. The curve is hardcoded to prime256v1.

In that case you should be able to verify a signature like this:

public_key = {{:ECPoint, pk_bytes}, {:namedCurve, :prime256v1}}
:public_key.verify(message, :sha256, signature, public_key)

Hi voltone,

That looks promising thanks! Unfortunately I don’t have time to try it right away but I will give that a try perhaps somewhere tomorrow.

It took a while before I finally was able to test this but it works like a charm. Thanks Voltone!