Calculate HMAC in Google BigQuery SQL

落爺英雄遲暮 提交于 2020-03-23 08:25:18

问题


How do I calculate an HMAC in Google BigQuery?

BigQuery includes a number of crypto related functions, such as hash functions and encryption functions, but a HMAC function (that calculates a signature) is missing.


回答1:


The BigQuery developers apparently forgot to add HMAC functions, but fortunately that can be built on what is available. HMAC is defined as

HMAC(Key, Message) = H((Key xor opad) concat H((Key xor ipad) concat Message))

where H is a hash function and Key, ipad and opad are all byte strings of the same length as the blocksize of the hash function.

BigQuery provides all the necessary building blocks to implement this in custom functions. The following code implements HMAC_SHA1, but you can change it to use a different hash function by replacing the hash function and updating the block size.

-- HMAC(K, M) = H((K xor opad) concat H((K xor ipad) concat M))
-- K, opad and ipad are all the same size as the hash function's block size
-- ipad = 0x36 repeated to fill the block size
-- opad = 0x5c repeated to fill the block size
-- If K is smaller than the block size, it must be padded with 0x00s

-- This implementation gives the same result as the online HMAC generator at https://www.freeformatter.com/hmac-generator.html


create temp function blocksize() as (64); -- the block size of the hash function, 64 in the case of SHA1
create temp function ipad() as (repeat(b"\x36", blocksize()));
create temp function opad() as (repeat(b"\x5c", blocksize()));

create temp function pad(key BYTES) as (
  concat(key, repeat(b"\x00", blocksize() - byte_length(key)))
);

create temp function hash_if_needed(key BYTES) as (
  if(byte_length(key) > blocksize(), sha1(key), key)
);

-- size of key == block size
create temp function hmac_sha1_core(key BYTES, message BYTES) as (
  sha1(concat(
    key ^ opad(),
    sha1(concat(key ^ ipad(), message))
  ))
);

-- key must not be larger than the block size
create temp function hmac_sha1_bytes(key BYTES, message BYTES) as (
  hmac_sha1_core(pad(key), message)
);

create temp function hmac_sha1(key STRING, message STRING) as (
  hmac_sha1_bytes(hash_if_needed(cast(key as BYTES)), cast(message as BYTES))
);

To verify, try select to_hex(hmac_sha1("my secret key", "hello world")) and compare it to the hmac generated on https://www.freeformatter.com/hmac-generator.html



来源:https://stackoverflow.com/questions/57430935/calculate-hmac-in-google-bigquery-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!