问题描述
我对这里需要为 Python 做的事情有点困惑,但是从 Yubikey API 文档中验证具有 YubiOTP 的 Yubikeys 需要以特定方式生成 HMAC 签名 - 从他们的 documentation :
生成签名
该协议使用 HMAC-SHA-1 签名。要使用的 HMAC 密钥是 客户端 API 密钥。
对消息中的参数生成签名。每个 消息包含一组键/值对,并且签名总是 在整个集合(不包括签名本身),并排序 键的字母顺序。更准确地说,生成消息 签名做:
-
按键顺序按字母顺序对键/值对集进行排序。
-
用每个有序的键/值对构造一行 使用 & 连接,每个键和值都用
=
连接。做 不要添加任何换行符。不要添加空格。例如:a=2&b=1&c=3
。 -
在行上应用 HMAC-SHA-1 算法作为八位字节字符串使用 API 密钥作为密钥(记得对从 尤比科)。
-
Base 64 根据 RFC 4648 对结果值进行编码,例如 例如,
t2ZMtKeValdA+H0jVpj3LIichn4=
。 -
将键 h 下的值附加到消息中。
现在我从他们的文档中了解他们的 API 声明了以下有效的请求参数:
-
id
- Yubico API 的客户端 ID -
otp
- 来自 yubikey 的 YubiOTP 组件的 YubiOTP 值。 -
h
- 请求的 HMAC-SHA1 签名 -
timestamp
- empty 什么都不做,1
包括服务器回复中的时间戳 -
nonce
- 包含随机唯一数据的 16 到 40 个字符长的字符串。 -
sl
- 0 到 100 之间的值,表示客户端所需的同步百分比,或字符串“fast”或“Secure”以使用服务器值;如果不存在的服务器决定 -
timeout
- 等待同步响应的秒数;让服务器决定是否缺席。
我一共尝试使用两个函数来尝试处理所有这些事情并生成 URL。即,我们的 HMAC 支持函数和生成 URL 的 verify_url_generate
(并且 API_KEY
是静态编码的 - 我的来自 Yubico 的 API 密钥):
def generate_signature(message,key=base64.b64decode(API_KEY)):
message = bytes(message,'UTF-8')
digester = hmac.new(key,message,hashlib.sha1)
digest = digester.digest()
signature = base64.urlsafe_b64encode(digest)
return str(signature,'UTF-8')
def verify_url_generate(otp):
nonce = "".join(secrets.choice(ascii_lowercase) for _ in range(40))
data = OrderedDict(
{
"id": None,"nonce": None,"otp": None,"sl": 50,"timeout": 10,"timestamp": 1
}
)
data['otp'] = otp
data['id'] = CLIENT_ID
data['nonce'] = nonce
args = ""
for key,value in data.items():
args += f"{key}={value}&"
sig = generate_signature(args[:-1])
url = YUBICO_API_URL + args + "&h=" + sig
print(url)
return
由此生成的任何 URL 都会触发来自远程站点的有关“BAD_SIGNATURE”的通知 - 生成的任何 URL 减去 HMAC sig (h=
) 参数都有效。所以我们知道问题不在于 URL,而在于 HMAC 签名。
有谁知道我的 HMAC 生成方法做错了什么,通过向 HMAC sig 生成器传递 key=value
中由 &
分隔的有序 dict 中的连接 args,用于每个参数格式?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)