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

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:

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

Where Next?

Popular in Questions Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
malloryerik
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
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
shahryarjb
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
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement