为什么 nodejs/express 中的 cookie-signature 使用 sha1-hashing 比较签名?
Why does cookie-signature in nodejs/express compare signatures using sha1-hashing?
我只是在研究允许创建签名 cookie 的 express 加密签名扩展的实现。
签名函数中的 mac 的计算方式如下:
- 创建一个 SHA256 实例
- 散列数据值
- 创建一个 base64 编码的摘要
- 删除结尾的相等字符 ('=')
结果是原始值和计算值 mac 的串联。
在验证签名后,将再次对值进行签名。但随后不是对签名进行相等性测试,而是比较由原始值和附加的 mac 组成的整个字符串:
return sha1(mac) == sha1(val) ? str : false;
此处 "mac" 包含与新计算的 mac 连接的原始值,"val" 包含传递给验证方法的输入字符串(由与前 mac) 和 "str" 是有符号值本身。
参见:https://github.com/tj/node-cookie-signature/blob/master/index.js
我原以为只有 mac 会被比较。但这种情况并非如此。为什么作者选择这种方式来实现验证?这是什么原因?特别是:他们为什么不逐个字符地比较一个字符,而是比较 sha1 的哈希值?
实现的sign
函数returns将值与'.'
和HMAC连接起来的值转换为Base64而不尾随的“=”(如果有)。
实现的 unsign
函数对给定输入的 value 部分执行相同的操作(直到 '.'
)并检查 整个 输入等于sign
函数的输出。
关于使用哈希值进行比较,作者试图抵制 timing attack,攻击者会观察到逐个字符检查相等性并根据两次尝试之间的微小变化来确定所花费的时间检查失败的字符是什么,然后尝试逐个字符地猜测任意 value 部分的 MAC 值。通过比较,使用 sha1
摘要代码需要常数时间,仅取决于给定的 整个 输入长度。
更有趣的旁注是从 Base64 编码的 MAC 中删除填充 '=',我不知道他们为什么要这样做,因为有 URL safe variant 的 Base64。
我只是在研究允许创建签名 cookie 的 express 加密签名扩展的实现。
签名函数中的 mac 的计算方式如下:
- 创建一个 SHA256 实例
- 散列数据值
- 创建一个 base64 编码的摘要
- 删除结尾的相等字符 ('=')
结果是原始值和计算值 mac 的串联。
在验证签名后,将再次对值进行签名。但随后不是对签名进行相等性测试,而是比较由原始值和附加的 mac 组成的整个字符串:
return sha1(mac) == sha1(val) ? str : false;
此处 "mac" 包含与新计算的 mac 连接的原始值,"val" 包含传递给验证方法的输入字符串(由与前 mac) 和 "str" 是有符号值本身。
参见:https://github.com/tj/node-cookie-signature/blob/master/index.js
我原以为只有 mac 会被比较。但这种情况并非如此。为什么作者选择这种方式来实现验证?这是什么原因?特别是:他们为什么不逐个字符地比较一个字符,而是比较 sha1 的哈希值?
实现的sign
函数returns将值与'.'
和HMAC连接起来的值转换为Base64而不尾随的“=”(如果有)。
实现的 unsign
函数对给定输入的 value 部分执行相同的操作(直到 '.'
)并检查 整个 输入等于sign
函数的输出。
关于使用哈希值进行比较,作者试图抵制 timing attack,攻击者会观察到逐个字符检查相等性并根据两次尝试之间的微小变化来确定所花费的时间检查失败的字符是什么,然后尝试逐个字符地猜测任意 value 部分的 MAC 值。通过比较,使用 sha1
摘要代码需要常数时间,仅取决于给定的 整个 输入长度。
更有趣的旁注是从 Base64 编码的 MAC 中删除填充 '=',我不知道他们为什么要这样做,因为有 URL safe variant 的 Base64。