将初始化向量和盐与密文一起传递是不是不安全?

Posted

技术标签:

【中文标题】将初始化向量和盐与密文一起传递是不是不安全?【英文标题】:Is it insecure to pass initialization vector and salt along with ciphertext?将初始化向量和盐与密文一起传递是否不安全? 【发布时间】:2011-04-20 11:09:56 【问题描述】:

我是加密的新手,似乎还在学习基础知识。

我的开源代码库需要对称加密功能。该系统包含三个组件:

存储一些用户数据的服务器,以及有关是否加密以及如何加密的信息 一个 C# 客户端,允许用户在发送到服务器时使用简单的密码加密他们的数据,并在接收时使用相同的密码解密 具有相同功能的 javascript 客户端,因此必须与 C# 客户端的加密方法兼容

查看各种 JavaScript 库,我发现了 SJCL,这里有一个可爱的演示页面:http://bitwiseshiftleft.github.com/sjcl/demo/

由此看来,为了解密密文,客户端需要知道的(除了使用的密码)是:

初始化向量 密码上使用的任何盐 密钥大小 身份验证强度(我不完全确定这是什么)

将所有这些数据与密文一起保存是否相对安全?请记住,这是一个开源代码库,除非我要求用户记住它们(是的,正确的),否则我无法合理地隐藏这些变量。

任何建议表示赞赏。

【问题讨论】:

旁白:此数据只能由用户在登录时访问,当然也可以由任何有权访问服务器的系统管理员访问。它不公开分享。 【参考方案1】:

初始化向量和盐被称为这样,而不是键,正是因为它们不需要保密。将此类数据与加密/散列元素一起编码是安全且习惯的。

IV 或 salt 只需要使用给定的密钥或密码使用一次。对于某些算法(例如 CBC 加密),可能有一些额外的要求,通过随机选择 IV 来满足,具有统一的概率和加密强的随机数生成器。但是,对于 IV 或盐来说,机密性并不是必需的属性。

对称加密很少足以提供安全性;加密本身可以防止被动攻击,攻击者会观察但不干预。为了防止主动攻击,您还需要某种身份验证。 SJCL 使用 CCM 或 OCB2 加密模式,结合了加密和认证,所以没问题。 “身份验证强度”是加密文本中专用于身份验证的字段的长度(以位为单位); “64 位”的强度意味着试图更改消息的攻击者有 2-64 的最大概率成功这样做而不会被身份验证机制检测到(并且他不知道他是否没有尝试就成功了,即将更改的消息发送给知道密钥/密码的人)。这对于大多数用途来说已经足够了。更大的身份验证强度意味着更大的密文,数量(大致)相同。

我没有看过实现,但从文档看来,SJCL 的作者知道他们的行业,并且做得很好。我建议使用它。

记住密码和 Javascript 的常见注意事项:

Javascript 是在客户端运行但从服务器下载的代码。这要求以某种方式对下载进行完整性保护;否则,攻击者可能会注入一些他自己的代码,例如一个简单的补丁,该补丁还会记录用户在某处输入的密码的副本。实际上,这意味着应该通过 SSL/TLS 会话(即 HTTPS)提供 SJCL 代码。

用户是人类,人类不擅长选择密码。这是人脑的局限。此外,计算机不断变得越来越强大,而人类的大脑则或多或少地保持不变。这使得密码对字典攻击越来越弱,即对密码进行详尽搜索(攻击者试图通过尝试“可能的”密码来猜测用户的密码)。 SJCL 生成的密文可用于离线字典攻击:攻击者可以在他自己的计算机上“尝试”密码,而无需针对您的服务器检查密码,并且他仅受他自己的限制计算能力。 SJCL 包含一些使离线字典攻击更加困难的功能:

    SJCL 使用盐,它可以防止成本分摊(通常称为“预计算表”,特别是“彩虹表”,它是一种特殊的预计算表)。至少攻击者将不得不为每个被攻击的密码支付字典搜索的全部费用。 SJCL重复使用盐,通过一遍又一遍地用密码散列它来生成密钥。这就是 SJCL 所说的“密码强化因素”。这使得密码到密钥的转换对于客户端来说更加昂贵,但对于攻击者来说也是如此,这就是重点。将密钥转换时间延长 1000 倍意味着用户将不得不等待,也许是半秒;但它也将攻击者的成本乘以 1000。

【讨论】:

哇,谢谢,这正是我想要的解释!

以上是关于将初始化向量和盐与密文一起传递是不是不安全?的主要内容,如果未能解决你的问题,请参考以下文章

对称加密的分组加密模式以及go语言实现

可以将用户的盐与密码哈希保存在同一个表中吗?

在向量大括号初始化中将 C 数组传递给结构初始化程序

将向量地址转换为本机指针是不是安全?

markdown 盐与Terraform一起使用的例子

SWIG:如何将复数向量从 C++ 传递到 python