Search code examples
pythongoogle-cloud-storageelixirsha256

Trying to create a sha256 key and hash in Elixir (converting from python code)


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!


Solution

  • 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}"