看来,我刚开始实施加密,并且仍在学习基础知识。
我的开源代码库中需要对称加密功能。此系统包含三个组件:
一台存储一些用户数据的服务器,以及有关是否对其进行加密以及如何加密的信息
一个C#客户端,允许用户在发送到服务器时使用简单的密码加密数据,并在接收时使用相同的密码解密
具有相同功能的JavaScript客户端,因此必须与C#客户端的加密方法兼容
在查看各种JavaScript库时,我遇到了SJCL,在这里有一个漂亮的演示页面:http://bitwiseshiftleft.github.com/sjcl/demo/
由此看来,客户端要解密密文需要知道的内容(除了使用的密码)是:
初始化向量
密码上使用的所有盐
密钥大小
验证强度(我不太确定这是什么)
将所有这些数据保留为密文相对安全吗?请记住,这是一个开放源代码库,除非我要求用户记住它们(是的,对),否则我无法合理地隐藏这些变量。
任何建议表示赞赏。
最佳答案
初始化向量和盐之所以称为这样的,而不是称为密钥,正是因为它们不需要保密。将此类数据与加密/散列元素一起编码是安全且习惯的。
IV或盐的需要仅与给定的键或密码一起使用一次。对于某些算法(例如CBC加密),可能会有一些额外的要求,这些要求可以通过以均等概率随机地选择IV并使用密码学上强的随机数生成器来满足。但是,机密不是IV或盐的必要属性。
对称加密很少能提供安全性。加密本身就可以防止被动攻击,攻击者可以观察到但不进行干预。为了防御主动攻击,您还需要某种身份验证。 SJCL使用结合了加密和身份验证的CCM或OCB2加密模式,因此很好。 “认证强度”是加密文本内专用于认证的字段的长度(以位为单位);强度为“ 64位”的意思是,尝试更改消息的攻击者在没有被身份验证机制检测到的情况下最大成功的可能性为2-64(并且他不知道自己是否已经成功而没有尝试,即具有更改后的消息发送给知道密钥/密码的人)。对于大多数目的而言,这就足够了。更高的身份验证强度意味着(大约)相同数量的更大密文。
我没有看过实现,但是从文档看来,SJCL作者似乎了解他们的交易,并且做得很好。我建议使用它。
记住密码和Javascript通常的警告:
Javascript是在客户端运行但从服务器下载的代码。这就需要以某种方式保护下载的完整性。否则,攻击者可能会注入自己的一些代码,例如一个简单的补丁程序,该补丁程序还将用户输入的密码的副本记录在某处。实际上,这意味着应在SSL / TLS会话(即HTTPS)中提供SJCL代码。
用户是人类,人类在选择密码时很不好。它是人脑的局限性。此外,计算机的功能越来越强大,而人脑的功能却越来越多。这使得密码越来越难以接受字典攻击,即对密码的详尽搜索(攻击者尝试通过尝试“可能”的密码来猜测用户的密码)。 SJCL生成的密文可用于脱机字典攻击:攻击者可以在自己的计算机上“尝试”密码,而不必对照服务器进行检查,并且仅受其自身计算能力的限制。 SJCL包括一些使离线字典攻击更加困难的功能:
SJCL使用盐来防止成本分摊(通常称为“预计算表”,特别是“彩虹表”,这是一种特殊的预计算表)。至少攻击者将必须为每个被攻击的密码支付字典搜索的全部费用。
SJCL反复使用盐,方法是一遍又一遍地用密码对它进行哈希处理以生成密钥。这就是SJCL所谓的“密码加强因素”。这一点对于客户端和攻击者而言,使密码到密钥的转换变得更加昂贵。将密钥转换时间延长1000倍,意味着用户将不得不等待半秒钟。但它也会使攻击者的成本乘以1000。