bananaphone
Create ED25519 JWK & JWT, later extract Subject and Kid from JWT
I am trying to create a JWT using an existing ED25519 key, then later extract the subject from it, and the kid to verify it. Here is what I have so far:
def generate_my_jwk() do
raw_private_key =
Base.decode16!(Application.get_env(:balls_pds, :owner_private_key), case: :lower)
generate_jwk(raw_private_key)
end
def generate_jwk(raw_private_key) when is_binary(raw_private_key) do
public_key = :crypto.generate_key(:eddsa, :ed25519, raw_private_key) |> elem(0)
jwk = %{
"kty" => "OKP",
"alg" => "EdDSA",
"crv" => "Ed25519",
"d" => Base.url_encode64(raw_private_key, padding: false),
"x" => Base.url_encode64(public_key, padding: false),
"use" => "sig"
}
JOSE.JWK.from(jwk)
end
def generate_jwt(days \\ 30) when is_integer(days) and days > 0 do
jwk = generate_my_jwk()
signer = Joken.Signer.create("EdDSA", jwk)
id = Application.get_env(:balls_pds, :owner_ap_id)
claims = %{
"iss" => id,
"sub" => id,
"aud" => Application.get_env(:balls_pds, :owner_ap_id),
"iat" => DateTime.utc_now() |> DateTime.to_unix(),
"exp" => DateTime.utc_now() |> DateTime.add(30, :day) |> DateTime.to_unix()
}
Joken.generate_and_sign!(claims, signer)
end
defp get_kid(jwt) when is_binary(jwt) do
with {:kid, {:ok, %{"kid" => kid}}} <- {:kid, JOSE.JWT.peek_protected(jwt)} do
kid
else
_ -> nil
end
end
def extract_key_info(jwt) when is_binary(jwt) do
with {:subject, {:ok, %{"sub" => subject}}} <- {:subject, JOSE.JWT.peek_payload(jwt)},
{:kid, kid} <- {:kid, get_kid(jwt)} do
{:ok, %{subject: subject, id: kid}}
else
{err, {:error, error}} ->
Logger.error("extracting key info from JWT: #{err}: #{inspect(error)}")
{:error, error}
end
end
I created this through a combination of Internet searching, reading source code, trial and error, and asking an AI for help. However I only get this far:
% mix generate_token
** (FunctionClauseError) no function clause matching in JOSE.JWK.from_record/1
The following arguments were given to JOSE.JWK.from_record/1:
# 1
{:error, {:missing_required_keys, ["keys", "kty"]}}
Attempted function clauses (showing 2 out of 2):
def from_record({:jose_jwk, keys, kty, fields})
def from_record(list) when is_list(list)
(jose 1.11.10) lib/jose/jwk.ex:35: JOSE.JWK.from_record/1
(joken 2.6.2) lib/joken/signer.ex:107: Joken.Signer.create/3
(balls_pds 0.0.9) lib/balls_pds/jwt.ex:64: BallsPDS.JWT.generate_jwt/1
(balls_pds 0.0.9) lib/mix/tasks/generate_token.ex:5: Mix.Tasks.GenerateToken.run/1
(mix 1.17.3) lib/mix/task.ex:495: anonymous fn/3 in Mix.Task.run_task/5
(mix 1.17.3) lib/mix/cli.ex:96: Mix.CLI.run_task/2
/Users/user/.asdf/installs/elixir/1.17.3-otp-27/bin/mix:2: (file)
I could use any guidance for doing this properly, and hints of where to look to learn how to do this as I had trouble just finding information.
Marked As Solved
ruslandoga
![]()
I think the problem are these two lines
jwk = generate_my_jwk()
signer = Joken.Signer.create("EdDSA", jwk)
Joken.Signer.create/2 doesn’t expect JOSE.JWK.t() but rather a plain map with string keys, ["keys", "kty"] in particular.
This seems to work:
$ openssl genpkey -algorithm ed25519 > test_key.pem
$ cat test_key.pem
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIMAjXAcsE6G7AWpRQWK4eLnVRxakXforWuebGlRaGKgC
-----END PRIVATE KEY-----
Mix.install([:jose, :joken, :jason])
test_key = """
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIMAjXAcsE6G7AWpRQWK4eLnVRxakXforWuebGlRaGKgC
-----END PRIVATE KEY-----
"""
jwk = JOSE.JWK.from_pem(test_key)
{_, jwk_map} = JOSE.JWK.to_map(jwk)
Joken.Signer.create("EdDSA", jwk_map)
But I’ve never used Joken before and don’t actually know what it does ![]()
3
Popular in Questions
Hi! May someone helps me, please!
I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it.
I’m very interested in Elixir,...
New
I would like to know what is the best IDE for elixir development?
New
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
I tried installing
elixir 1.11.2
erlang 23.3.4
via asdf in my zsh shell. Enabled the versions locally and globally.
When I list them ...
New
Hello, I have map which I want to convert it to string like this:
the map:
%{last_name: "tavakkoli", name: "shahryar"}
the string I ne...
New
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
Other popular topics
Phoenix 1.4.0 released
Phoenix 1.4 is out! This release ships with exciting new features, most notably
with HTTP2 support, improved deve...
New
Hello, I get Persian date from my client and convert it to normal calendar like this:
def jalali_string_to_miladi_english_number(persi...
New
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode.
The solution seems to be, in a hyphena...
New
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this
"1000"
What is the ...
New







