Skip to content

Commit 92a9885

Browse files
committed
Also optimize signing
1 parent 8bd5997 commit 92a9885

1 file changed

Lines changed: 20 additions & 43 deletions

File tree

lib/plug/crypto/message_verifier.ex

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -36,61 +36,38 @@ defmodule Plug.Crypto.MessageVerifier do
3636

3737
## Signature Algorithms
3838

39-
defp hmac_sha2_to_protected(:sha256), do: "HS256"
40-
defp hmac_sha2_to_protected(:sha384), do: "HS384"
41-
defp hmac_sha2_to_protected(:sha512), do: "HS512"
39+
defp hmac_sha2_to_protected(:sha256), do: "SFMyNTY"
40+
defp hmac_sha2_to_protected(:sha384), do: "SFMzODQ"
41+
defp hmac_sha2_to_protected(:sha512), do: "SFM1MTI"
4242

43-
defp hmac_sha2_to_digest_type("HS256"), do: :sha256
44-
defp hmac_sha2_to_digest_type("HS384"), do: :sha384
45-
defp hmac_sha2_to_digest_type("HS512"), do: :sha512
43+
defp hmac_sha2_to_digest_type("SFMyNTY"), do: :sha256
44+
defp hmac_sha2_to_digest_type("SFMzODQ"), do: :sha384
45+
defp hmac_sha2_to_digest_type("SFM1MTI"), do: :sha512
4646

4747
defp hmac_sha2_sign(payload, key, digest_type) do
4848
protected = hmac_sha2_to_protected(digest_type)
49-
plain_text = signing_input(protected, payload)
49+
plain_text = [protected, ?., Base.url_encode64(payload, padding: false)]
5050
signature = :crypto.mac(:hmac, digest_type, key, plain_text)
51-
encode_token(plain_text, signature)
51+
IO.iodata_to_binary([plain_text, ".", Base.url_encode64(signature, padding: false)])
5252
end
5353

5454
defp hmac_sha2_verify(signed, key) when is_binary(signed) and is_binary(key) do
55-
case decode_token(signed) do
56-
{protected, payload, plain_text, signature} when protected in ["HS256", "HS384", "HS512"] ->
57-
digest_type = hmac_sha2_to_digest_type(protected)
58-
challenge = :crypto.mac(:hmac, digest_type, key, plain_text)
59-
60-
if Plug.Crypto.secure_compare(challenge, signature) do
61-
{:ok, payload}
62-
else
63-
:error
64-
end
65-
66-
_ ->
67-
:error
68-
end
69-
end
70-
71-
## Helpers
72-
73-
defp encode_token(plain_text, signature)
74-
when is_binary(plain_text) and is_binary(signature) do
75-
plain_text <> "." <> Base.url_encode64(signature, padding: false)
76-
end
77-
78-
defp decode_token(token) do
79-
with [protected, payload, signature] <- String.split(token, ".", parts: 3),
55+
with [protected, payload, signature] when protected in ["SFMyNTY", "SFMzODQ", "SFM1MTI"] <-
56+
:binary.split(signed, ".", [:global]),
8057
plain_text = [protected, ?., payload],
81-
{:ok, protected} <- Base.url_decode64(protected, padding: false),
8258
{:ok, payload} <- Base.url_decode64(payload, padding: false),
8359
{:ok, signature} <- Base.url_decode64(signature, padding: false) do
84-
{protected, payload, plain_text, signature}
60+
digest_type = hmac_sha2_to_digest_type(protected)
61+
challenge = :crypto.mac(:hmac, digest_type, key, plain_text)
62+
63+
if Plug.Crypto.secure_compare(challenge, signature) do
64+
{:ok, payload}
65+
else
66+
:error
67+
end
8568
else
86-
_ -> :error
69+
_ ->
70+
:error
8771
end
8872
end
89-
90-
defp signing_input(protected, payload) when is_binary(protected) and is_binary(payload) do
91-
protected
92-
|> Base.url_encode64(padding: false)
93-
|> Kernel.<>(".")
94-
|> Kernel.<>(Base.url_encode64(payload, padding: false))
95-
end
9673
end

0 commit comments

Comments
 (0)