【发布时间】:2010-11-11 21:01:49
【问题描述】:
默认情况下,Ruby on Rails 将会话数据存储在 cookie 中。这有很多优点,例如不需要在服务器端设置任何持久层。但是,会话数据未加密,并且我正在编写的 Rails 应用程序将潜在的敏感数据放入会话中。如果可能,我想避免在服务器端存储会话数据,并且 Rails 唯一现有的加密 cookie 存储实现似乎已被放弃,所以我正在编写自己的加密 cookie 存储。
Rails cookie 会话存储的工作方式如下:
- 它将会话数据序列化为字节字符串。
- 序列化数据转换为base64。
- base64 数据由 HMAC 附加。 Rails 要求 HMAC 密钥至少为 30 字节;默认情况下,Rails 生成一个 128 字节的随机字符串作为密钥,从 /dev/urandom 获得。用于 HMAC 的默认哈希算法是 SHA-1。
- base64 数据 + HMAC 作为 cookie 发送到 HTTP 客户端。
- 当客户端执行请求时,Rails 首先检查 HMAC 验证是否成功。如果不是,那么它将默默地丢弃 cookie 中的会话数据,就好像用户根本没有发送任何会话数据一样。这也意味着如果管理员更改了 HMAC 密钥,那么所有旧会话都会自动失效。
- base64 数据经过去 base64 处理并解组为 Ruby 数据结构。
我正在编写的加密 cookie 会话存储是普通 cookie 存储类的子类。它的工作原理如下:
- 它会插入一个步骤 3.5:在步骤 3 之后,它将加密数据。
- 它修改了第 5 步:在检查 HMAC 之前,它会解密数据。
- 加密算法是 CFB 模式下的 AES-256。我了解 EBC 会暴露重复模式。
- 该代码要求管理员指定正好为 32 字节的加密密钥。加密密钥未经过哈希处理。默认情况下,它建议使用从 /dev/urandom 获得的随机生成的恰好 32 字节的加密密钥。
- 它还要求管理员指定一个正好为 16 字节的初始化向量。 IV 没有经过哈希处理,默认情况下,它建议使用从 /dev/urandom 获得的随机生成的 IV。
我之所以在加密前使用 HMAC(而不是在加密后使用 HMAC)是因为我希望能够检测到加密密钥或 IV 的更改。如果更改了加密密钥或 IV,我希望该软件自动使旧会话无效。如果我在加密后进行 HMAC,那么如果我更改加密密钥或 IV,HMAC 验证将通过,这是不可取的。
我的方法安全吗?如果没有,那还缺少什么?
一些注意事项:
- 我想按照http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html 的建议使用 CTR,但不幸的是 OpenSSL(包含在 Ruby 标准库中)不支持 CTR,我不想要求我的用户安装单独的第三方加密库。
- 我想为 HMAC 使用 SHA-256。 daemonology.net 建议不要使用 SHA-512,因为可能存在“对 32 位系统的侧信道攻击”(无论这意味着什么)。但是,并非每个平台都支持 SHA-256 作为 HMAC 的散列算法。最值得注意的是,OS X 上的 Ruby 不支持 HMAC+SHA256。我希望我的代码也能在 OS X 上开箱即用。
【问题讨论】:
标签: ruby-on-rails security encryption cryptography aes