[英]Generating HMAC signature with hashed “password”
我在RESTful API项目中使用身份验证方法,我非常喜欢生成HMAC-SHA256签名作为身份验证方法的想法。
客户端只需几个简单的步骤即可创建签名:
# example client-side code
sig = hmac.new(bytes('SUPER_SECRET_KEY', 'utf-8'), b'', sha256)
sig.update(request_path)
sig.update(request_body)
# ...other variables needed for generating the signature...
signature = sig.hexdigest()
并将其及其“用户名”添加到请求标头(例如, Authorization: THE_USER_NAME:abcd1234xyz890
)。
在服务器端,我试图以相同的方式重新创建它:
# example server-side code
def do_check(request):
# get user name from request header
username = request.headers['Authorization'].split(':')[0]
# some method to retrieve the "secret key" from database
user = db.User().filter(username=username).one()
# use user's "secret key" to generate the signature
sig = hmac.new(bytes(user.key, 'utf8'), b'', sha256)
sig.update(bytes(request.path, 'utf-8'))
sig.update(request.data)
# ...other variables needed for generating the signature...
return sig.hexdigest()
# compare the returned signature with the one client sent us...
只要我将用户的密钥以纯文本格式存储在数据库中,这一切就可以正常工作:
| username | key |
------------------------------------
| THE_USER_NAME | SUPER_SECRET_KEY |
我们都知道这绝对是不可接受的 ,因此我尝试使用bcrypt
简单地对SUPER_SECRET_KEY
进行哈希处理并存储一个哈希处理的字符串:
| username | key |
--------------------------------------------------------------------------------
| THE_USER_NAME | $2b$12$UOIKEBFBedbcYFhbXBclJOZIEgSGaFmeZYhQtaE4l6WobFW1qvIf6 |
我现在面临的问题是,客户端使用了未加密的“秘密密钥”版本来生成签名,由于不再使用纯文本格式,因此无法在服务器端进行签名。
一种类似方法的示例之一是在Amazon Web Services中生成HMAC签名 (也是同一过程的简化说明 ),它不需要任何其他登录或身份验证,也不需要为密钥/提供任何令牌或“替换”。秘密组合。 我真的怀疑AWS是否将秘密以纯文本格式存储在数据库中(?)
如何在数据库中使用哈希表的“秘密密钥”的哈希版本在服务器端重新创建HMAC签名,而又不强制客户端更改其签名生成方法(例如,避免安装bcrypt
甚至根本不加密密钥)?
密码哈希不使用共享机密。 散列密码的行为应该破坏实际值,同时保留对密码进行身份验证的能力。 不能合理地期望您从哈希中恢复密码。
Hmac身份验证和验证使用共享机密。 双方都必须知道这个秘密。
因此,密码散列与hmac根本不同,您不能简单地散列hmac密钥。 哈希将不允许您返回到实际密钥。
[澄清后删除不相关的部分]
因此,您必须在某处具有某种机密,但不必将其保存在数据库中。 可以使用对称密码(使用不在数据库中的其他密钥)在数据库中对实际的hmac共享密钥进行加密。 因此,服务器读取加密的hmac秘密密钥,然后对其进行解密并使用。
重要的是您必须以某种可以解密的方式对其进行加密,从而排除了哈希。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.