The idea behind this is that :rpc
is not encrypted.
Setting up TLS just for :rpc
is yucky. So maybe there is a safer way than just plain HTTP but not as safe as TLS?
This will not encrypt your cookie, but it will encrypt the arguments!
Set an Environment variable: System.put_env("RPC_TOKEN", "NjkmlOJ343jkhKJAH")
Or in bash: export RPC_TOKEN=NjkmlOJ343jkhKJAH
Now the idea is on one distributed node:
payload = %{hello: ["world", "earth", {42, 9000}]}
secret_list = SafeRpc.encrypt(payload)
:rpc.call(
:name@host,
MyMod,
:my_fun,
[:saferpc, secret_list]
)
Now on the other node you pattern match :saferpc
and decrypt the secret list:
defmodule MyModule do
def my_fun(:saferpc, secret_list) do
my_map = SafeRpc.decrypt(secret_list)
IO.inspect my_map
end
end
Now you have your data!
This works with any term! 🎉
Here is an example of the lib itself and a dry run:
System.put_env("RPC_TOKEN", "Njk##mlOJ(&#$)788Hn!@343jkhKJAH")
defmodule SafeRpc do
@secret System.get_env("RPC_TOKEN") |> to_charlist
@secret_length System.get_env("RPC_TOKEN") |> to_charlist |> length
def encrypt(term) do
term
|> :erlang.term_to_binary
|> :binary.bin_to_list
|> Enum.with_index
|> Enum.map(fn {e, i} -> (e + 1) * secret_char(i) end)
end
def decrypt(list) do
list
|> Enum.with_index
|> Enum.map(fn {e, i} -> (e - 1) / secret_char(i) |> trunc end)
|> :binary.list_to_bin
|> :erlang.binary_to_term
end
defp secret_char(i) do
Enum.at(@secret, rem(i, @secret_length))
end
end
secret_term_list = SafeRpc.encrypt(%{hello: ["world", 'earth', {42, 9000}]})
IO.inspect secret_term_list
IO.inspect SafeRpc.decrypt(secret_term_list)
# OUTPUT OF PROGRAM
[10296, 12402, 107, 35, 35, 218, 10908, 79, 444, 4200, 3876, 3815, 3924, 4592,
5995, 56, 56, 72, 440, 3630, 64, 51, 52, 306, 12720, 11984, 11960, 8175, 7474,
7150, 72, 78, 106, 642, 3570, 3430, 12535, 12636, 8295, 7770, 120, 3724, 1505,
3564, 41, 55, 2016, 2296, 7704]
%{hello: ["world", 'earth', {42, 9000}]}