criptografia sha-256 no Planilhas Google usando scripts de aplicativos

Aug 26 2020

Estou tentando criptografar 3 elementos diferentes em um token de autenticação para cabeçalhos http para uma API. Esta API é integrada ao Planilhas Google e não posso usar mais nada no momento.

O token de autenticação requer 4 partes:

  1. Chave API
  2. Timestamp no formato UTC
  3. Ação API
  4. Chave secreta API

No formato de API KEY: TIMESTAMP: API ACTION: API Secret Key

Para os fins deste exemplo, digamos que o

  1. A chave da API é test123,
  2. Data UTC: Qui, 14 de abril de 2011 22:44:22 GMT
  3. A ação da API é 'razão'
  4. A chave secreta da API é UAV213Q

Quando testei o exemplo usando o seguinte formato " test123: Thu, 14 Apr 2011 22:44:22 GMT: ledger: UAV213Q " em python, obtive o resultado 15594d1f608134cbfa3075ecda4664519cd198738b8f5c3ffa2c95272b854199

Este é o script python que usei

def sha256():
    # tested on Python 3.8.5
    from urllib import parse, request
    import hashlib
    import datetime
    from time import strftime, gmtime

    # credentials and request params
    my_merchant_id = 'apikey'
    api_token = 'test123'
    api_secret_key = 'UAV213Q'
    my_timestamp = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
    api_version = 2.9
    action_verb = 'ledger'

    # set up request params
    data = parse.urlencode({'merchantId': my_merchant_id, 'token': api_token,
                        'version': api_version, 'action': action_verb})

    # authentication
    sig = api_token + ':' + my_timestamp + ':' + action_verb + ':' + api_secret_key
    sig_hash = hashlib.sha256(sig.encode('utf-8')).hexdigest()
    my_headers = {'x-ShareASale-Date': my_timestamp,
                'x-ShareASale-Authentication': sig_hash}

    print(sig_hash)

Tentei usar as soluções das seguintes outras perguntas sobre StackOverFlow: Como faço para que o Google Apps Script faça criptografia SHA-256? , sha3-256 de um texto de célula na planilha do Google , todas as sugestões.

No entanto, continuo recebendo a mensagem de erro "Esta função não tem permissão para fazer referência a uma célula com NOW (), RAND () ou RANDBETWEEN ()."

Eu tentei referenciar uma célula que indiretamente faz referência a NOW () tendo NOW () em A1 e tendo B1 = A1, eu até tentei convertê-la em texto usando TEXT ().

A chave de API precisa ter o carimbo de data / hora para funcionar. Eu estava pensando em ter isso calculado no próprio script do App, já que é uma constante conhecida. Por exemplo, dentro do script de criptografia, ele codificaria o token da API, chamaria o carimbo de data / hora no formato utc e codificaria a chave secreta da API no formato correto e talvez apenas a função para adicionar a ação para que eu possa fazer a alteração para que seja sha256 (livro-razão) e incorporaria isso à criptografia

Respostas

3 Tanaike Aug 26 2020 at 16:02

Que tal essa resposta?

Pontos de modificação:

  • Quando vi seu script Python, confirmei que a especificação mostrada em sua pergunta é diferente daquela do script Python.
    • Parece que Thu, 14 Apr 2011 22:44:22 GMTéThu, 14 Apr 2011 22:44:22 +0000
    • Parece que é necessário usar "SHA_256" do resumo.

Script de amostra:

Quando seu script Python é convertido em Google Apps Script, ele se torna o seguinte. Copie e cole no editor de script e execute a função myFunctionno editor de script. Com isso, você pode ver o valor do resultado no log.

function myFunction() {
  const api_token = 'test123';
  const api_secret_key = 'UAV213Q';
  const my_timestamp = 'Thu, 14 Apr 2011 22:44:22 +0000';
  const action_verb = 'ledger';

  const value = `${api_token}:${my_timestamp}:${action_verb}:${api_secret_key}`;
  const bytes = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, value);
  const res = bytes.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
  console.log(res)
}

Resultado:

Quando test123:Thu, 14 Apr 2011 22:44:22 +0000:ledger:UAV213Qé usado para o Google Apps Script acima e seu script Python, os dois resultados são iguais aos seguintes.

8c3a6873fe71c402dc1e3ca7bc828712e3dfb7a66ed09feeeca2152dd809df81

Referência:

  • computeDigest (algoritmo, valor)

Adicionado:

Resposta para a pergunta adicional 1:

Quando você quiser recuperar a string de data como Thu, 14 Apr 2011 22:44:22 +0000, use o seguinte script.

const my_timestamp = new Date().toUTCString().replace("GMT", "+0000");

Resposta para a pergunta adicional 2:

Quando você quiser recuperar o valor em maiúsculas, use o seguinte script. Mas quando testei seu script Python, o valor do resultado está em minúsculas. Portanto, tenha cuidado com isso.

function myFunction() {
  const api_token = 'test123';
  const api_secret_key = 'UAV213Q';
  const my_timestamp = 'Thu, 14 Apr 2011 22:44:22 +0000';
  const action_verb = 'ledger';

  const value = `${api_token}:${my_timestamp}:${action_verb}:${api_secret_key}`;
  const bytes = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, value);
  const res = bytes.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('').toUpperCase();
  console.log(res)
}
  • Neste caso, 8C3A6873FE71C402DC1E3CA7BC828712E3DFB7A66ED09FEEECA2152DD809DF81é obtido.

Referências:

  • toUTCString ()
  • toUpperCase ()