开发人员在密码学方面应该在什么抽象级别上工作?

信息安全 密码学 编程
2021-08-18 05:28:03

我最近看到了 Jeff Atwood 的一篇旧博客文章,这让我开始思考。

有什么比 EncryptStringForBrowser() 方法更容易的了,它内置了安全性和防篡改功能,它是经过验证的、经过领域专家测试的代码集的一部分,成千上万甚至数百万的开发人员已经依赖这些代码?

显然,密码学的第一条规则是永远不要自己滚动。但是,开发人员应该走多远呢?

他们应该建立在编程语言中的密码库之上吗?他们应该使用第三方密码库吗?或者他们应该更进一步并使用一个可以处理所有事情的库,例如用于 PHP 的uLogin 。

如果要使用第三方库,非密码学家如何验证该库的安全性,除了它的声誉。

4个回答

密码学的一半是关于原始算法的,例如SHA-256AES另一半是将这些算法组装成完整的协议,例如SSL/TLS设计安全协议并不比构建安全算法容易。当开发人员干预算法时,根据定义,他正在创建自己的协议,即进行自己的加密。因此,建议谨慎。

在理想的世界中,开发人员会:

  1. 分析他试图解决的问题;
  2. 找到与他的问题相匹配的现有、经过审查、彻底验证的协议;
  3. 使用具有精心设计的 API 的库,该 API 实现了协议(及其底层加密算法),并小心翼翼地处理此类事情。

不幸的是,现实世界恰好是真实的,即根本不理想。可用的库通常有一个难以使用的 API,主要是因为库设计者过于热情:他煞费苦心地了解协议是如何工作的,并且他想分享. 因此,他制作了一个 API,该 API 公开了协议内部的许多工作原理,图书馆用户对此感到困惑。

此外,没有那么多现成的协议。您想找到一个适用于您的问题的协议;但是您经常不得不挤压和推挤和折磨您的问题,直到它看起来适合少数现有的“通用”协议之一(即 SSL 或 bcrypt)。当你唯一的工具是锤子时,所有问题都被强烈期望像钉子一样。

而且,当然,开发人员不会分析他们的问题。他们首先对其进行编码,然后将密码学作为一种对不安全恶魔的驱魔。

开发人员不必考虑密码学,除非在非常高的抽象层次上使用现有的协议实现。但是由于它不实用,由于普遍缺乏现成的协议和可用的实现,开发人员必须亲自动手并了解密码学的最细微的细节这不是密码学领域特有的,但密码学有一个令人讨厌的特点,那就是你无法测试安全性:只有让很多人仔细观察并认真思考,你才能知道你的产品是安全的。如果您不在已经进行此类审查的现有协议之外,那么您注定要进行自己的思考。

现在,如果您认为我的结论是,平均而言,没有掌握它的开发人员会草率地应用密码学,从而导致无数漏洞和普遍的混乱状态,那么您猜对了。

我的收获是:

  • 如果可以避免的话,永远不要使用自己的密码学。(有时您必须使用量身定制的解决方案/嵌入式平台。)如果您必须自己动手,请始终建立在已知的工作协议上。
  • 不要依赖隐藏你的实现。混淆是一种有效的深度防御层,但只能用于增加现有的安全性,而不是您的主要安全性来源。
  • 使用具有某种信任和声誉的第三方产品。对于 C/C++/Objective C,我使用 SSL 库PolarSSL的加密部分PolarSSL 几乎没有内部和外部依赖项,您只需拆下您需要的部分,PolarSSL 已经过荷兰政府的审查自己检查并不是一个真正的选择。

不是最好的答案,但我想说开发人员需要学习足够多的知识才能就项目风险做出正确的决定。

我已经看到任何项目都需要对整个系统有足够了解的人才能:

  • 诊断和修复部件无法连接的情况 - 随着您尝试连接在一起的不同系统的数量增加。
  • 可以测试以确保按预期实施加密。
  • 可以判断加密功能需要“多好​​”以及它们应该放置在哪里。

有一个人非常非常了解这些东西,可以为其他人建立一个模式,这是一个很好的做法。在我从事的大多数 Web 开发项目中,我们都有一个关于如何启动安全会话以及哪些情况需要该模式的模式,以及与安全身份验证相关的第二组模式。这被写成一个可重用的工具集,所以它可以被其他人使用,他们在最抽象的层次上工作。

如何选择技术基础与其他任何事情一样,都是高级架构决策,如果您有很大的风险,您需要聘请具有专业知识的人来了解要审查的内容。我看到的一个常见问题是,普通软件工程师会专注于特定类型的关注点(通常是算法的强度),而忽略了系统仅与最薄弱环节一样安全的大局,因此良好的实践与密码学(内存处理、输入验证、证书分发的适当措施)完全分开 - 与密码设备的强度一样重要(如果不是更重要的话)。

在低成本、低风险的环境中,我赞成完全按照平台提供商所说的方式进行安全工作。它降低了集成的复杂性,而且通常并不疯狂……只要您完全按照指导进行。所以它把“永远不要自己动手”的格言提升到了第 n 级。

随着风险和安全要求的增加,需要有人可以评估权衡并尝试其他选项。在我遇到的几乎每个平台中,默认加密库的功能都存在一些严重的限制。打破标准指导的方式可能从非常简单和低风险到不可能,从高风险到安全,或者只是集成起来很昂贵。该领域的问题可以通过两种主要方式制造或破坏产品 - 整合不常见的场景可能会将产品成本推高,或者您可能会引入您没有预见到的安全风险,从而影响产品并且可能导致发布后的业务灾难......这两种情况都可以通过雇佣具有安全控制集成经验的人员来缓解,

在一家高端安全开发商店工作过,我可以说我见过的最佳实践是在这个领域进行大量指导,在这些领域中,已经制作过以前产品的开发人员通过审查架构选择和计算来指导新工程师超出每种情况所需的抽象级别。

上面的一些问题没有正确答案……例如:

他们应该建立在编程语言中的密码库之上吗?

有时。例如,.NET 和 Java 都具有完全可接受的 SSL 实现,但如果您更改身份验证机制,或者尝试与算法选择非常有限的专用设备集成,它们都会变得困难。在许多情况下,标准加密协议的默认实现限制了您进行配置选择或捆绑更复杂的附加组件的能力,而无需破解封面。

他们应该使用第三方密码库吗?

有时——我最常这样做,尤其是当我需要比编程语言本身提供的更复杂的选项时。这里的挑战是,在许多高端环境中,一些第三方库没有经过充分审查以供客户批准,或者您可能会受到不断发展的产品的摆布,而这种产品对您的需求不稳定。也就是说,随着时间的推移,在这一领域有经验的开发人员会在给定的框架中建立一组最喜欢的 API。

或者他们应该更进一步,使用一个可以处理所有事情的库,例如用于 PHP 的 uLogin。

如果它有效,当然。我承认,根据我的经验,我不得不多次破解封面,以提供专门的身份验证方法或解决与不定期支持的设备集成的需要 - 所以我很少想到这样的整体包作为一个可行的选择 - 但我愿意打赌我的经验是极端情况。

每当您放弃这么多选择时,您必须希望实现者做出与您相同的选择。调查该领域的黑客攻击并查看漏洞是什么是值得的。

如果要使用第三方库,非密码学家如何验证该库的安全性,除了它的声誉。

这是一个简单的 - 有一些标准:

  • FIPS - 涵盖加密库或设备满足一定程度的保护规范。最低级别包括纯软件实现

  • 通用标准 - 涵盖大量设备、操作系统和其他产品 - 这是对产品是否按照文档所述执行的测试。

这是我最常见的两个来源,但我敢打赌还有其他来源。我还检查了行业的时间长度和升级的支持模型。当我寻找加密产品时,我会寻找一定的寿命和广泛的互操作性测试,以及分发补丁和响应检测到的漏洞的清晰方法。例如,看到 US-CERT 漏洞发布和产品升级之间存在很长的延迟,这将是一个不好的迹象。但没有看到任何US-CERT 漏洞并不是一个好兆头——这可能表明该产品的市场份额如此之低,以至于没有人试图打破它。

如果你问这些标准是否完美——我会说不。但这是一个很好的迹象,表明该产品已经推出了足够长的时间来投资其中一些认证,这意味着他们已经投入了一些认真的精力来确保安全特性符合要求。

昨晚我完成了斯坦福大学专业发展中心提供的在线课程。视频讲座由著名密码学家兼斯坦福大学教授 Dan Boneh 主持。他说了一句让我印象深刻的话,我想和你分享,那就是:

  1. 不要尝试实现自己的加密协议(正如您已经说过的)。
  2. 不要使用专有版本的加密协议(正如您所逃避的那样)。
  3. 确保正确使用加密库。换句话说,如果您需要经过身份验证的消息完整性,即使您有可证明的安全库,MAC'ing 然后加密(而不是加密然后 MAC'ing)仍然可以泄漏有关您的明文的信息。Boneh 教授提到,他经常看到加密货币在实践中被错误地使用。

我想,作为一个非密码学家,要确保图书馆是安全的,唯一的方法就是问一个密码学家?否则,很难证明函数/库实际上是安全的。

我知道我说的是学术意义而不是实际意义,但我只是想我会分享我学到的东西。我认为他处于加密社区的最前沿,他的演讲给我留下了深刻的印象。