17

看来,我是实施加密的新手,仍在学习基础知识。

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

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

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

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

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

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

任何建议表示赞赏。

4

1 回答 1

35

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

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

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

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

记住密码和 Javascript 的常见警告:

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

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

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