I am in the middle of creating an Elixir project that uses Google Cloud Storage. Some of our customer requirements dictate that each customer utilize their own separate encryption keys.
I can create them using the Google code provided manually, however I was wondering about automating this (mostly out of my curiosity). The python code provided by Google is:
import base64
import hashlib
import os
key = os.urandom(32)
print "Key: %sSHA256 hash: %s" % (base64.encodestring(key), base64.encodestring(hashlib.sha256(key).digest()))
I thought I put together some Elixir code to do the trick:
key = 32 |> :crypto.strong_rand_bytes |> Base.encode64
hash = :sha256 |> :crypto.hash(key) |> Base.encode64
IO.puts "Key: #{key}\nSHA256 hash: #{hash}"
However, when I try to use my Elixir-generated key and hash Google complains as so:
{
"domain": "global",
"extendedHelp": "https://cloud.google.com/storage/docs/encryption#customer-supplied_encryption_keys",
"message": "Missing a SHA256 hash of the encryption key, or it is not base64 encoded, or it does not match the encryption key.",
"reason": "customerEncryptionKeySha256IsInvalid"
}
Naturally, the Python code works, so there seems to be some difference going on here.
Anyone have any ideas as to why this is? Thanks!
It seems that in elixir, you are hashing the base64 encoded key, while the original python implementation hashes the raw bytes of the key.
The following should work:
key = :crypto.strong_rand_bytes(32)
base64_key = Base.encode64(key)
base64_hash = :sha256 |> :crypto.hash(key) |> Base.encode64
IO.puts "Key: #{base64_key}\nSHA256 hash: #{base64_hash}"