7

我正在考虑切换到将会话数据存储在加密的 cookie 中,而不是在我的服务器上的某个地方。虽然这会导致每个请求使用更多的带宽 - 它会节省额外的数据库服务器负载和存储空间。

无论如何,我计划使用RIJNDAEL 256 加密 cookie 内容。

function encrypt($text, $key) 
{
    return mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$text,MCRYPT_MODE_ECB,mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,MCRYPT_MODE_ECB),MCRYPT_RAND)); 
}

在使用中会产生这样的东西(base64 编码用于显示)

print base64_encode(encrypt('text', 'key'));

7s6RyMaYd4yAibXZJ3C8EuBtB4F0qfJ31xu1tXm8Xvw=

我并不担心单个用户的 cookie 被泄露,因为我担心攻击者会发现key并能够为任何用户构建任何会话,因为他们知道我使用什么来签署数据。

有没有办法可以验证与使用的参数相关的估计开裂时间?或者是否有与使用的文本或键的大小相关的标准时间度量?

我听说有人说密钥本身需要超过 256 位才能安全地与 RIJNDAEL 一起使用。我还想知道加密文本的长度是否需要一定长度才能不泄露密钥。

数据一般为200个字符左右

a:3{s:7:"user_id";i:345;s:5:"token";s:32:"0c4a14547ad221a5d877c2509b887ee6";s:4:"lang";s:2:"en";}

那么这安全吗?

4

5 回答 5

17

是的 Rijndael(AES) 是安全的,但是您的实施远非安全。您的实施有 2 个未解决的问题。ECB 模式的使用和您的 IV 是一个静态变量,将用于所有消息。 IV 必须始终是 Cryptographic Nonce。您的代码明显违反了 CWE-329。

永远不应使用 ECB 模式,必须使用 CBC 模式,原因如下:

原来的:

替代文字

使用 ECB 模式加密:

替代文字

使用 CBC 模式加密:

替代文字

于 2010-10-31T04:09:38.727 回答
3

避免使用欧洲央行。它可以揭示有关加密内容的信息。具有相同明文的任何两个块将具有相同的密文。CBC 可以避免这种情况,但需要生成或保存 IV。

避免简单地保存密钥和 IV。使用强加密随机数生成器生成 256 位主密钥,并将其保存到您的应用程序中安全的地方。使用它来生成用于加密的会话密钥。IV 可以从会话密钥中导出。生成会话密钥时,包括可用于缩小会话密钥范围的所有可用数据。(例如,包括 cookie 的范围、远程主机地址、与加密数据一起存储的随机通知和/或用户 ID(如果它不在加密数据中))

根据数据的使用方式,您可能必须包含 MAC。ECB 和 CBC 并非旨在检测密文的任何更改,此类更改将导致明文垃圾。您可能希望在加密数据中包含 HMAC,以允许您在将其作为规范之前对其进行身份验证。会话 HMAC 密钥必须从会话加密密钥派生。或者,您可以使用 PCBC 模式。PCBC 用于检测密文的变化,但它的能力受到填充大小的限制,这取决于加密的数据,并非所有加密 API 都将其作为选项。

一旦你已经包含了一个 MAC,那么你应该考虑采取措施来对抗重放攻击。任何时候有人可以在会话范围内重新发送旧数据都是重放攻击的机会。在不给用户造成问题的情况下尽可能缩小会话密钥的使用范围是阻止重放攻击的一种方法。您可以做的另一件事是在加密数据中包含日期和时间,以便在数据被视为有效时创建一个窗口。

在夏天,保护钥匙只是冰山一角。

于 2010-10-30T22:04:31.497 回答
3

如果您使用长钥匙,我会说钥匙非常安全。一些需要关注的事情:

您正在将数据存储卸载到客户端。永远不要相信客户。这并不意味着您不能这样做,只是您要么必须将 cookie 中的数据视为不受信任(不要做出任何比基于它向用户显示什么“主题”更严重的决定)或提供用于验证数据的方法。

如何验证数据的一些示例是:

  • 包括盐(这样具有相同会话数据的人不会得到相同的 cookie)和
  • 校验和(这样即使更改了一点 cookie 的人也会使其无用)。
于 2010-10-31T02:22:22.620 回答
2

Rijndael 更名为 AES。是的,它可以安全使用。

也就是说,您应该仔细考虑放入 cookie 中的内容。这取决于您系统上可用的存储方式,但您可以简单地选择一个随机数(例如 64 位数字),并将其存储在 cookie 中。在您的服务器端系统中,您会记录该号码与谁相关联以及其他详细信息。这完全避免了加密。您使用其他详细信息来验证(在可以验证的范围内)该 cookie 是否是从您最初将其发送到的浏览器发回的。

或者,您可以为每个会话使用不同的加密密钥,跟踪哪个密钥用于哪个会话。

即使您使用固定密钥进行直接加密,也要考虑在要加密的数据中包含一个随机数——这使得使用已知的明文攻击更难破解,因为根据定义,随机数是未知的。

于 2010-10-30T19:46:04.423 回答
0

AES-128 应该绰绰有余,无需使用更长的密钥 - 如果密钥是随机选择的。

但是还有其他问题。首先是你不应该使用欧洲央行。对于 ECB,如果密钥相同,则给定的 128 位明文块总是映射到相同的 128 位密文。这意味着攻击者可以通过手术修改密文,注入他们知道相应密文的不同块。例如,他们可以混合两个不同用户的数据。对于其他模式,例如 CBC 就可以了,密文还取决于 IV(初始化向量),在算法的每次执行中应该是不同的。这样,相同的明文每次都被不同地加密,对手无法获得任何优势。您还需要将IV与密文一起保存在某处,无需保护它。每当重用相同 IV 的机会变得不可忽略时,您也应该更改密钥。

第二个问题是您还应该附加一个消息验证码。否则,您将无法区分伪造的 cookie 和好的 cookie。

于 2010-10-30T22:05:54.803 回答