Dre*_*rew 31 encryption aes ctr-mode
我想加密由webapp写的cookie,我想保持cookie的大小最小,因此我选择了AES/CTR/NoPadding.
你会建议使用什么作为IV足够随机并仍然保持应用程序无状态.我知道我可以生成随机IV并将其附加到消息中,但这会增加cookie的大小.
另外,对于128位AES,建议的IV大小是多少?
大家都这样做了吗?是否存在任何"经过尝试和真实"的方式?我不想重新发明轮子.
Tho*_*nin 50
CTR安全性要求您永远不要将IV用于具有相同密钥的两个消息加密.实际上它甚至更严格:CTR模式通过加密计数器的连续值(IV只是该计数器的初始值)来工作,只有当相同的计数器值没有被使用两次时才能实现适当的安全性; 这意味着使用IV加密值实际上"消耗"一系列连续的IV值,这些值不能与另一个加密一起重复使用.
这样做的简单方法是使用加密安全的随机数生成器,并为每条消息创建一个新的16字节随机IV.我强调"加密安全",因为这很重要; 一个基本的随机数发生器是不够的.使用Java,使用java.util.SecureRandom.用Win32,打电话CryptGenRandom().通过随机选择,可能的128位IV空间足够大,以至于碰撞极不可能.实际上,这就是AES使用128位块(因此意味着128位IV)的原因.
将解密消息的实体必须知道IV,因此您必须将其与加密消息一起存储.这是额外的16个字节.我知道这个开销是你想要避免的,尽管16个字节对于cookie来说并不是那么多.cookie的有效最大长度取决于Web浏览器,但4000个字符似乎"无处不在".一个16字节的IV,当用字符编码时(例如使用Base64),将使用大约22个字符,即远小于最大cookie大小的1%:也许你可以买得起?
现在我们可以变得时髦并尝试通过欺骗来减少IV长度:
使用散列函数生成IV:服务器端,使用计数器,从0开始,每次需要新的IV时递增.要获得IV,您可以使用合适的散列函数(例如SHA-256)对计数器进行散列,并保留散列值的前16个字节.散列函数的"随机化属性"足以使IV在CTR要求方面足够随机.这需要一个加密安全的哈希函数,因此需要SHA-256(避免使用MD5).然后,您只需将计数器值存储在cookie中,计数器将短于16个字节(例如,如果您的客户数不超过40亿,则计数器将适合4个字节).但是,有一个隐藏的成本:服务器(我想服务器正在你的系统中执行加密)必须确保它永远不会重用计数器值,所以它必须以一种持续存在的方式存储"当前计数器"服务器重新启动,如果扩展到多个前端,也不会失败.这似乎并不那么容易.
使用外部唯一值:可能,cookie可以是上下文的一部分,该上下文提供足够的数据来生成对每个加密都是唯一的值.例如,如果请求还包含(明确地)"用户ID",则可以将用户ID用作IV源.设置类似于上面的设置:您获得所有数据,将其填入SHA-256,SHA-256输出的前16个字节是您需要的IV.只有当给定的加密消息的数据没有变化,并且它确实是唯一的时,这才有效.这种情况很少发生:例如,只有在不需要为同一用户重新加密新消息的情况下,"用户ID"才有用,并且如果再也没有可能重用用户ID(例如,旧用户退出,新用户来,并选择现在免费的用户ID).
使用通过加密安全PRNG生成的随机16字节IV仍然是"安全"方式,也是我推荐的方式.如果你在cookie中发现空间紧张,那么这意味着你正在接近4 kB的限制,此时你可能想要使用压缩(在加密之前的数据上;在加密之后,压缩非常不可能工作).使用zlib(在Java中,您可以访问zlib java.util.zip).
警告:在所有上述情况,我不是说任何有关Cookie加密是否确实在提供你正在努力实现的任何安全特性帮助.通常,当需要加密时,您实际上需要加密和完整性,然后您应该使用组合加密和完整性模式.查找GCM和CCM.此外,cookie加密主要用于一个目的,这是为了避免存储服务器端一些用户特定数据的成本.如果你想为其他东西加密一个cookie,比如验证一个有效的用户,那么你做错了:加密不是正确的工具.
| 归档时间: |
|
| 查看次数: |
54371 次 |
| 最近记录: |