danish
October 25, 2018, 2:08pm
1
this is the function that I am trying to convert to Elixir:
private static byte[] HashBody(string content)
{
var contentBytes = Encoding.UTF8.GetBytes(content);
using (var provider = new SHA256Managed())
{
var hash = provider.ComputeHash(contentBytes);
return hash;
}
}
My attempt:
content = %{
"id" => "123",
"name" => "Jaqob"
} |> Poison.encode!
digest = :crypto.hash(:sha256, content)
I want to convert content variable to bytes which is where I am stuck, also is the hashing function correct?
1 Like
easco
October 25, 2018, 3:04pm
2
Your content variable is already a Binary (an Elixir string is a Binary) so it is already “bytes”.
Your code looks complete to me. Where are you having problems?
1 Like
Eiji
October 25, 2018, 3:05pm
3
How about using :erlang.term_to_binary/1
? With this you can work with any data you want unlike Poison
.
1 Like
I think @easco ’s answer is pretty much correct, but I’m guessing what you’re after is maybe a list of bytes? Since your C# code returns an array of bytes? You can use :erlang.binary_to_list/1
on digest
to convert the binary to a list.
3 Likes
danish
October 29, 2018, 5:46pm
5
Thanks for your prompt response @jordan0day , @Eiji , @easco
I needed to convert the map/json to string in order to match the hashed value.
I am now unable to match the Signature, in the elixir code I have include the expected Base64 string:
This is the signature code in C#:
public static string GenerateDigitalSignature(string body, string privateKeyText)
{
var hash = HashBody(body);
byte[] signedHash;
using (var privateKey = ImportPrivateKey(privateKeyText))
{
signedHash = privateKey.SignHash(hash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Console.WriteLine("signedHash");
}
var encodedHash = Convert.ToBase64String(signedHash);
Console.WriteLine(encodedHash);
return encodedHash;
}
and this is my code in elixir
def test(conn, _params) do
{:ok, rawSkey} = File.read("/home/danish/www/apis/signtest/keys/private_key.pem")
[encSKey] = :public_key.pem_decode(rawSkey)
sKey = :public_key.pem_entry_decode(encSKey)
string = "{\"MachineName\":\"DESKTOP-04VG548\",\"Userame\":\"inder\",\"Timestamp\":\"2018-10-26T20:58:48.7840832Z\"}"
msg = :crypto.hash(:sha256, string)
signature = :public_key.sign(msg, :sha256, sKey, [{:rsa_padding, :rsa_pkcs1_padding}])
|> Base.encode64
#
IO.inspect("signature")
IO.inspect(signature)
IO.inspect("EXPECTED SIGNATURE")
IO.inspect("1FdzHD5FhYFEbV9NpbXpE/CfrvHcv8p/LDQxMd900iZQxrSNbNqwQ/3coWO2Pof3nCmRIPicURyvp3+UrRALp/4eEFprdzmITFh9ojVrOvFI0FYqDsvEDQYvw6G2oX6vVw0b640dg3a+J3A8KEUs3RwSuiilSiqi/CeUzRNFhI3+7aPYF5p0QrAnoNmgmK6GbIY6eu0WnMxyJcGsrkE2KYWCqxrfMq5AiKIPdZVdXfLM6+0AoVw2Q7EgUILNRA91v2QGkdpBwvpHX5Feau2NspS8sq8zdTz8wEVHXC0GjLMqK5M1VvWAW+evYi15qqPOtYHXrvN2KJXjEwSbFdRc7A==")
json conn, "ok"
end
private_key:
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDo4LOhXxF5f3yU
BhOsyv4wiIn2aMpCiFYOd4X/TufdgBZc4DcTkXOqQ0piIcgnWN0pp9ZTXc5Fmj51
UO2/bs7uZedi/Q7zcHpuI8DB9tCa82cuGkx1uHzTRzQF3cEbkZD/7pC6mopCGOgJ
y8rGZWuKPzcyhNgmo9J0ou04Nkqvzsd3O8STaGd1eF3Q+eb2rWgSLOfYsuO4Fu13
JZJK+IJYA5oj5ci132KEi6LPK9HDHbb4u1ie5J1GvMgVUSD+MK4IP4lcJBbpQP5f
1dAJ4Y2/OTqv66YNeSSOdrVq36l2iSKErImk7B9GjKCuDAMLBgllI/nGgSRK5EdQ
Ke5i9VSlAgMBAAECggEBAImY8yo/JPEYDcDcklV/n4+HrZTFt/R13/suTiNbOQ8c
dpor9P7/60rH9bRj54KwNAU/4RhjDdT8XTkuNzvsOiKMXZqUkXfvlrdrMqKotftI
JEgOS+0ms8KWiLuKmmYyrW07RZKsa1LAqqHXIxn0pQULcw7LhXfXRiuadPXIxnp3
X8KvCy4BGk6J3OtWbhPT7Pz/ImPKc0TxKdiQMkY848ghDpo3+BVT2e69kfFkQd/6
j+ghjjs7RN9jniIxJGJYLDSwVngOaFt8SVe95r4tBw4Kr28T66E7WP8xyLwih6ZA
/+QVQr2f4WZtKSyHxDgfkCh3lvzAEXPBCs782peIYGECgYEA9dlgqaKxyqZwFsvK
dMTTSK9MgqOLKKv16AUMh+Zmvt/kBvqAO6FHqqOw44jYV6XtleUnO54c87/wxtOd
KNHR0tp69fWChwPVAeN42Dby8nG5SMpauE7oi9TkULmBXXVuKFDHw1s9TZ3vw69c
tBiKglI+ulXhWvZNng6vso4YMZkCgYEA8n43dm4ux5kNSszqk3CmhJUMC6yw1/Yo
V1NRAsmJ+3HnRS61TFzij3KjYbO5e975nXxC+S+Mw3vb5PnOUTpIew/ABQyLBAHE
CkNXVr65O+r9ePgFmJEHK8cWF7o5tMO7CxfqJohJFn2u9dq/WuaVhTxZN0r5TIBo
8tYupvsg+u0CgYEA3B5zM68drKn0thRlAsOvwOZjhJxVXmcI12Kd45fg6omfqrfi
1IEEn73MBQ1jVqaT4J+5zuE0XvG97OdPUVr7mORRL6NP6P7/Wp+GdWBNidFU6d1z
+I1+HKTSf4x4TWt049ff5APvEW2VXQnH4OAQM7rbuw5lpYHd4OSZXy9mbhECgYAi
Yo1gyLzvZp+A5M+6enXSRQRBP4qQBQKxZ0oMeCGNuxgNMlNY8a7aomnSd9asXvDM
SQuCJCD0s0J6FIYR9I7EjHYxARdRSSLQRb5DuaWwfmDU326DtMTsiz1xveFi5YJH
T2vPbPHYM5g0moEZ1aqMCwOnmIUDOQ4oqQBSgzeo/QKBgQCJMGKVdG9zVr/za4fS
mQaRm+U8gHoohozgczsD9dB9dHgm7KEXhi+S6LhQfks0GnQvg9MuNfW5zrYXf+rq
DVCOF6jtp3hHDEd+KdDUgikF3FnwGzcq8e1hRLGvcIvqWEb+psimekk1aaAgUyCj
2JOy9eD5+cReQ1vL3Eh6Vtg5vw==-----END PRIVATE KEY-----
what do you reckon I am doing wrong?
This line (above) is unnecessary: your call to :public_key.sign
already calculates a SHA256 over the input, so right now the input string is hashed twice. Just pass string
instead of msg
to the sign function.
3 Likes
BTW, just FYI and FWIW, a bit more idiomatic Elixir would be:
def test(conn, _params) do
raw_skey = File.read!("/home/danish/www/apis/signtest/keys/private_key.pem")
[enc_skey] = :public_key.pem_decode(raw_skey)
skey = :public_key.pem_entry_decode(enc_skey)
string = ~s("MachineName":"DESKTOP-04VG548","Userame":"inder","Timestamp":"2018-10-26T20:58:48.7840832Z"})
signature =
string
|> :public_key.sign(:sha256, skey, rsa_padding: :rsa_pkcs1_padding)
|> Base.encode64
IO.puts("signature")
IO.inspect(signature)
json conn, "ok"
end
5 Likes
danish
October 30, 2018, 9:24am
8
thank you @voltone , this resolves my issue.
1 Like