使用应用程序脚本在 Google 个工作表中进行 sha-256 加密
sha-256 encryption within Google Sheets using App Scripts
我正在尝试将 3 个不同的元素加密到一个身份验证令牌中,用于 API 的 http headers。此 API 内置于 Google 表格中,目前我无法使用其他任何东西。
身份验证令牌需要 4 个部分:
- API键
- UTC 格式的时间戳
- API 动作
- API 密钥
格式为API KEY:TIMESTAMP:API ACTION:API Secret Key
为了这个例子的目的,假设
- API关键是test123,
- UTC 日期:2011 年 4 月 14 日,星期四 22:44:22 GMT
- API 动作是 'ledger'
- API秘钥为UAV213Q
当我在 python 中使用以下格式“test123:Thu, 14 Apr 2011 22:44:22 GMT:ledger:UAV213Q”测试示例时,我得到了结果 15594d1f608134cbfa3075ecda4664519cd198738b8f5c3ffa2c95272b854199
这是我使用的python脚本
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)
我尝试使用以下其他 Whosebug 问题的解决方案
, ,所有建议。
但是,我不断收到错误消息“此函数不允许使用 NOW()、RAND() 或 RANDBETWEEN() 引用单元格。”
我曾尝试通过在 A1 中使用 NOW() 并使 B1 =A1 来引用间接引用 NOW() 的单元格,我什至尝试使用 TEXT() 将其转换为文本。
API 键需要有时间戳才能起作用。我正在考虑在 App 脚本本身中计算它,因为它是一个已知常量。例如,在加密脚本中,它会硬编码 api 令牌,以 utc 格式调用时间戳,并以正确的格式硬编码 api 密钥,也许只是添加操作的函数,这样我就可以进行更改,使其成为 sha256(ledger) 并将其合并到加密中
这个答案怎么样?
修改点:
- 当我看到您的 python 脚本时,我确认您问题中显示的规范与 python 脚本的规范不同。
- 好像
Thu, 14 Apr 2011 22:44:22 GMT
是Thu, 14 Apr 2011 22:44:22 +0000
- 看来必须使用摘要的“SHA_256”。
示例脚本:
当您的 python 脚本转换为 Google Apps 脚本时,它变成如下。请将其复制并粘贴到脚本编辑器,并在脚本编辑器中 运行 函数 myFunction
。这样就可以在日志中看到结果值了。
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)
}
结果:
当 test123:Thu, 14 Apr 2011 22:44:22 +0000:ledger:UAV213Q
用于上述 Google Apps 脚本和您的 python 脚本时,两者的结果相同,如下所示。
8c3a6873fe71c402dc1e3ca7bc828712e3dfb7a66ed09feeeca2152dd809df81
参考:
已添加:
附加问题 1 的答案:
当您想要检索像Thu, 14 Apr 2011 22:44:22 +0000
这样的日期字符串时,请使用以下脚本。
const my_timestamp = new Date().toUTCString().replace("GMT", "+0000");
附加问题 2 的答案:
当您想要检索大写的值时,请使用以下脚本。但是当我测试你的 python 脚本时,结果值是小写的。所以请注意这一点。
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)
}
- 在这种情况下,得到
8C3A6873FE71C402DC1E3CA7BC828712E3DFB7A66ED09FEEECA2152DD809DF81
。
参考文献:
我正在尝试将 3 个不同的元素加密到一个身份验证令牌中,用于 API 的 http headers。此 API 内置于 Google 表格中,目前我无法使用其他任何东西。
身份验证令牌需要 4 个部分:
- API键
- UTC 格式的时间戳
- API 动作
- API 密钥
格式为API KEY:TIMESTAMP:API ACTION:API Secret Key
为了这个例子的目的,假设
- API关键是test123,
- UTC 日期:2011 年 4 月 14 日,星期四 22:44:22 GMT
- API 动作是 'ledger'
- API秘钥为UAV213Q
当我在 python 中使用以下格式“test123:Thu, 14 Apr 2011 22:44:22 GMT:ledger:UAV213Q”测试示例时,我得到了结果 15594d1f608134cbfa3075ecda4664519cd198738b8f5c3ffa2c95272b854199
这是我使用的python脚本
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)
我尝试使用以下其他 Whosebug 问题的解决方案
但是,我不断收到错误消息“此函数不允许使用 NOW()、RAND() 或 RANDBETWEEN() 引用单元格。”
我曾尝试通过在 A1 中使用 NOW() 并使 B1 =A1 来引用间接引用 NOW() 的单元格,我什至尝试使用 TEXT() 将其转换为文本。
API 键需要有时间戳才能起作用。我正在考虑在 App 脚本本身中计算它,因为它是一个已知常量。例如,在加密脚本中,它会硬编码 api 令牌,以 utc 格式调用时间戳,并以正确的格式硬编码 api 密钥,也许只是添加操作的函数,这样我就可以进行更改,使其成为 sha256(ledger) 并将其合并到加密中
这个答案怎么样?
修改点:
- 当我看到您的 python 脚本时,我确认您问题中显示的规范与 python 脚本的规范不同。
- 好像
Thu, 14 Apr 2011 22:44:22 GMT
是Thu, 14 Apr 2011 22:44:22 +0000
- 看来必须使用摘要的“SHA_256”。
- 好像
示例脚本:
当您的 python 脚本转换为 Google Apps 脚本时,它变成如下。请将其复制并粘贴到脚本编辑器,并在脚本编辑器中 运行 函数 myFunction
。这样就可以在日志中看到结果值了。
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)
}
结果:
当 test123:Thu, 14 Apr 2011 22:44:22 +0000:ledger:UAV213Q
用于上述 Google Apps 脚本和您的 python 脚本时,两者的结果相同,如下所示。
8c3a6873fe71c402dc1e3ca7bc828712e3dfb7a66ed09feeeca2152dd809df81
参考:
已添加:
附加问题 1 的答案:
当您想要检索像Thu, 14 Apr 2011 22:44:22 +0000
这样的日期字符串时,请使用以下脚本。
const my_timestamp = new Date().toUTCString().replace("GMT", "+0000");
附加问题 2 的答案:
当您想要检索大写的值时,请使用以下脚本。但是当我测试你的 python 脚本时,结果值是小写的。所以请注意这一点。
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)
}
- 在这种情况下,得到
8C3A6873FE71C402DC1E3CA7BC828712E3DFB7A66ED09FEEECA2152DD809DF81
。