java aes初始向量_加密 – 如何为AES/CTR/NoPadding选择合适的IV(初始化向量)?

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个字节(例如,如果您的客户数量不超过4亿,计数器将以4个字节为准)。然而,有一个隐藏的成本:服务器(我认为服务器在你的系统中执行加密)必须确保它不会重复使用计数器值,所以它必须以一种持续存在的方式存储“当前计数器”服务器重新启动,如果您扩展到几个前端也不会失败。这似乎并不容易。

>使用外部唯一值:可能,cookie可以是提供足够数据以生成每个加密唯一的值的上下文的一部分。例如,如果请求还包含(清除)“用户ID”,则可以将用户ID用作IV源。该设置与上述相似:您获取所有数据,将其填入SHA-256,SHA-256输出的前16个字节是您需要的IV。这只有在给定的加密消息的数据没有变化的情况下才能起作用,如果它真的是唯一的。这是一个罕见的情况:例如,只有在永远不需要为同一用户重新加密新消息的情况下,“用户ID”才是有用的,如果永远不会有用户ID被重用的可能性(例如,一个旧用户退出,一个新用户来,并选择现在的免费用户ID)。

使用密码安全PRNG生成的随机16字节IV仍然是“安全”的方式,而我推荐的。如果您在cookie中发现空间紧张,则这意味着您正在接近4 kB限制,此时可能需要使用压缩(在加密之前的数据上,加密后压缩非常不太可能运行)。使用zlib(在Java中,您可以通过java.util.zip访问zlib)。

警告:在上述所有方面,我不是说cookie加密是否有助于提供您尝试实现的任何安全特性。通常,当需要加密时,实际上需要加密和完整性,然后应该使用组合加密和完整性模式。 Lookup GCM和CCM.此外,Cookie加密主要适用于一个目的,这是为了避免存储服务器端一点用户特定数据的成本。如果你想加密一个cookie的其他东西,例如验证一个有效的用户,那么你做错了:加密不是正确的工具。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值