Python HMAC 库源代码中 _secret_backdoor_key 变量的原因是什么?
What is the reason for _secret_backdoor_key variable in Python HMAC library source code?
今天在浏览Python HMAC模块源码的时候发现里面有全局变量_secret_backdoor_key
。然后检查此变量以中断对象初始化。
代码如下所示
# A unique object passed by HMAC.copy() to the HMAC constructor, in order
# that the latter return very quickly. HMAC("") in contrast is quite
# expensive.
_secret_backdoor_key = []
class HMAC:
"""RFC 2104 HMAC class. Also complies with RFC 4231.
This supports the API for Cryptographic Hash Functions (PEP 247).
"""
blocksize = 64 # 512-bit HMAC; can be changed in subclasses.
def __init__(self, key, msg = None, digestmod = None):
"""Create a new HMAC object.
key: key for the keyed hash object.
msg: Initial input for the hash, if provided.
digestmod: A module supporting PEP 247. *OR*
A hashlib constructor returning a new hash object.
Defaults to hashlib.md5.
"""
if key is _secret_backdoor_key: # cheap
return
有谁知道这个变量的原因是什么?评论说 HMAC 比空白字符串 ("") 更快 return。但是为什么用户要将空密钥传递给 HMAC 函数呢?变量命名只是 HMAC 开发者的玩笑还是真的是某种后门?
要创建 HMAC 实例的副本,您需要先创建一个空实例。
_secret_backdoor_key
对象用作提前退出 __init__
的哨兵,而不是 运行 通过 __init__
功能的其余部分。 copy
方法然后直接设置实例属性:
def copy(self):
"""Return a separate copy of this hashing object.
An update to this copy won't affect the original object.
"""
other = self.__class__(_secret_backdoor_key)
other.digest_cons = self.digest_cons
other.digest_size = self.digest_size
other.inner = self.inner.copy()
other.outer = self.outer.copy()
return other
您可以使用 self.__class__('')
(空字符串)获得相同的效果,但是 HMAC.__init__
会做很多不必要的工作,因为创建的实例上的属性将被替换 无论如何。请注意,使用 HMAC('')
是创建实例的 有效方法 ,在这种情况下,您不希望实例没有任何状态。通过传入哨兵,HMAC.copy()
可以避免所有这些额外的工作。
您可以使用不同的 'flag' 值,例如 False
,但由于您自己的代码中存在错误,因此传递该值太容易了。相反,您希望收到此类错误的通知。通过使用 'secret' 内部哨兵对象,您可以避免此类意外情况。
使用[]
作为哨兵唯一对象是一种很古老的做法。这些天你会使用 object()
来代替。这个想法是哨兵是一个 唯一的单个对象 ,您可以用 is
来测试它的身份。您无法在别处重新创建该对象,is
测试仅在您传入对完全相同的单个对象的引用时才有效。
今天在浏览Python HMAC模块源码的时候发现里面有全局变量_secret_backdoor_key
。然后检查此变量以中断对象初始化。
代码如下所示
# A unique object passed by HMAC.copy() to the HMAC constructor, in order
# that the latter return very quickly. HMAC("") in contrast is quite
# expensive.
_secret_backdoor_key = []
class HMAC:
"""RFC 2104 HMAC class. Also complies with RFC 4231.
This supports the API for Cryptographic Hash Functions (PEP 247).
"""
blocksize = 64 # 512-bit HMAC; can be changed in subclasses.
def __init__(self, key, msg = None, digestmod = None):
"""Create a new HMAC object.
key: key for the keyed hash object.
msg: Initial input for the hash, if provided.
digestmod: A module supporting PEP 247. *OR*
A hashlib constructor returning a new hash object.
Defaults to hashlib.md5.
"""
if key is _secret_backdoor_key: # cheap
return
有谁知道这个变量的原因是什么?评论说 HMAC 比空白字符串 ("") 更快 return。但是为什么用户要将空密钥传递给 HMAC 函数呢?变量命名只是 HMAC 开发者的玩笑还是真的是某种后门?
要创建 HMAC 实例的副本,您需要先创建一个空实例。
_secret_backdoor_key
对象用作提前退出 __init__
的哨兵,而不是 运行 通过 __init__
功能的其余部分。 copy
方法然后直接设置实例属性:
def copy(self):
"""Return a separate copy of this hashing object.
An update to this copy won't affect the original object.
"""
other = self.__class__(_secret_backdoor_key)
other.digest_cons = self.digest_cons
other.digest_size = self.digest_size
other.inner = self.inner.copy()
other.outer = self.outer.copy()
return other
您可以使用 self.__class__('')
(空字符串)获得相同的效果,但是 HMAC.__init__
会做很多不必要的工作,因为创建的实例上的属性将被替换 无论如何。请注意,使用 HMAC('')
是创建实例的 有效方法 ,在这种情况下,您不希望实例没有任何状态。通过传入哨兵,HMAC.copy()
可以避免所有这些额外的工作。
您可以使用不同的 'flag' 值,例如 False
,但由于您自己的代码中存在错误,因此传递该值太容易了。相反,您希望收到此类错误的通知。通过使用 'secret' 内部哨兵对象,您可以避免此类意外情况。
使用[]
作为哨兵唯一对象是一种很古老的做法。这些天你会使用 object()
来代替。这个想法是哨兵是一个 唯一的单个对象 ,您可以用 is
来测试它的身份。您无法在别处重新创建该对象,is
测试仅在您传入对完全相同的单个对象的引用时才有效。