@@ -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
9673end
0 commit comments