ttakashinn

ttakashinn

Troubleshooting AWS CloudFront Signed URL Generation for Accessing S3 Images

I’m trying to generate a signed URL using AWS CloudFront to access images stored on AWS S3.

Here’s the code snippet to retrieve the private key.

defp load_private_key() do
    System.get_env("AWS_PRIVATE_KEY")
    |> Base.decode64!()
    |> :public_key.pem_decode()
    |> hd()
    |> :public_key.pem_entry_decode()
  end

And here’s the code snippet to generate the signed URL.

defp generate_cloudfront_signed_url(s3_object_key) do
    private_key = load_private_key()
    key_pair_id = System.get_env("AWS_KEY_PAIR_ID")

    # Generate CloudFront signed URL
    generate_cloudfront_signed_url(s3_object_key, private_key, key_pair_id)
  end

  defp generate_cloudfront_signed_url(s3_object_key, private_key, key_pair_id) do
    url = get_object_url(s3_object_key)
    expires_when = calculate_expiration_in_unix_time()
    policy = create_custom_policy(url, expires_when)

    signature = :public_key.sign(policy, :sha, private_key)
    # signature = :crypto.sign(:rsa, :sha, policy, private_key)
    encoded_signature = Base.url_encode64(signature)

    "#{url}?Expires=#{expires_when}&Signature=#{encoded_signature}&Key-Pair-Id=#{key_pair_id}"
  end

However, when accessing the generated URL, I always encounter an error.

<Error>
<Code>MalformedSignature</Code>
<Message>Could not unencode Signature</Message>
</Error>

If anyone has experience working with CloudFront and S3, please help me out. Thank you very much.

Marked As Solved

ttakashinn

ttakashinn

https://github.com/Frameio/cloudfront-signer/blob/master/lib/cloudfront_signer/signature.ex

Thank you for your response. After referring to the code in the file above, I discovered the error was in the line

signature = :public_key.sign(policy, :sha, private_key)
encoded_signature = Base.url_encode64(signature)

Base.url_encode64 didn’t encode signature correctly as CloudFront requires. After changing it to

encoded_signature =
      policy
      |> :public_key.sign(:sha, private_key)
      |> Base.encode64()
      |> String.to_charlist()
      |> Enum.map(&replace/1)
      |> to_string()
#---------
@compile {:inline, replace: 1}
  defp replace(?+), do: ?-
  defp replace(?=), do: ?_
  defp replace(?/), do: ?~
  defp replace(c), do: c

I was able to create the signed URL normally.

Thank you.

Also Liked

karlosmid

karlosmid

Hi! In my previous project, I was using Elixir Arc library for that:
https://github.com/stavro/arc?tab=readme-ov-file#url-generation

Here is my blog post how to sign and extend default signature valid duration:

Where Next?

Popular in Questions Top

Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&amp;query=perfume&amp;page=2, I would like to get: ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
JDanielMartinez
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
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement