程序员密码学 1:基础知识
密码学基本原理
BubblePress @AliasKepler
前几天我读到一篇文章,讨论了有多少流行的安卓应用在代码中存在基本的加密漏洞。分析使用了哥伦比亚大学的 Crylogger,这是一款用于检测加密漏洞的开源动态分析工具。我对结果有些惊讶(所有被分析的应用都至少违反了他们选定的 26 条加密规则中的一条),但情况也并不十分意外。我自己在参与的项目中也遇到过不止一条这样的规则被违反的情况。对于那些从未学习过加密技术、不了解其基础知识的人来说,这些规则很难直观地理解。而且大多数程序员通常从未以结构化的方式正确学习过加密技术。当普通程序员想要在他们的项目中实现某种加密技术时,他们会像处理其他问题一样:在 Stack Overflow 上寻找解决方案。加密代码的问题在于,即使它看起来有效,也并不意味着它是安全的。在某些情况下完全安全的加密代码,在另一种情况下可能毫无用处。另一个常见问题是,新项目通常不太关心安全性,而是将其留待将来再处理。但有些情况下,后期重构的成本太高。如果您使用不安全的哈希值存储用户密码,那么除非用户重置密码,或者必须处理两种不同类型的哈希值,否则您将无法解决这个问题,因此错误仍然存在。然而,从一开始就安全地存储密码非常简单,并且不会花费任何额外的时间。
本系列旨在为程序员讲解密码学的基础知识,使他们的项目不会成为统计数据的一部分。有时,密码学似乎令人望而生畏。我的目的并非教授密码学算法的具体细节,也并非深入探讨学术密码学的细节和细微差别。我的目标是尽可能使其实用,同时提供最佳实践和应避免的错误。对于那些想深入了解我所讲内容的人,我将提供相关资料的链接。
我将为部分章节提供 TypeScript / Node 代码示例,但不建议直接使用这些代码,除非您阅读完整系列文章、理解代码并思考其是否真正适合您的问题。我还会提供一些不完整和不正确的代码,您可以在后续章节中进行改进。读完本系列文章后,读者应该能够理解并应用哥伦比亚大学为 Crylogger 选择的 26 条加密规则。
该系列将分为四个部分:
在第 1 部分(本部分)中,我将提供一些编写安全加密代码的基本通用规则。
在第二部分中,我将讨论区块密码学,这是一种最常用于数据加密/解密的密码学。我们还将讨论生成密钥和随机数的安全方法。
在第 3 部分中,我将讨论身份验证、密码和登录管理,我们将把它们放在一起以实现使用 JWT 登录。
在第 4 部分中,我将讨论公钥加密和互联网协议的基础知识(SSL/TLS、SSH 等)。
密码学基本原理
1. 避免不必要的复杂性
密码系统存在于更大的系统内部,并非孤立的组件。系统越复杂,就越有可能存在漏洞。而你的系统安全性取决于其中最不安全的组件。假设你非常自豪,因为你使用了最先进的密码算法,但你生成或存储密钥的方式却不安全。那么,即使密码学再好,密钥也很容易被攻击者获取,你的所有数据都可以轻松解密。你的代码中需要安全保护的部分越多,代码越复杂,就越有可能在某个时候被人搞砸。
2. 柯克霍夫原则:只有钥匙才是秘密
在密码安全中,只有加密/解密密钥(或非对称加密中的私钥)应该是保密的。这意味着,系统安全性应该设计得确保即使攻击者知道系统的所有信息(除了密钥),系统仍然是安全的。为了提高安全性,最常见的保密方式是代码。有些人甚至使用晦涩难懂/不常见的加密算法,这样攻击者就无法知道数据的加密方式。事实上,项目的代码并非秘密,因为团队中的每个程序员都掌握着它。因此,如果系统的安全性依赖于代码的保密性,那么你可能会赋予太多人过多的权力。
正确的做法是将密钥保密,只有少数值得信赖的员工才能访问(理想情况下,他们无法读取或复制密钥,只能使用),这也是系统安全唯一可依赖的秘密。黑客向公司员工提供金钱以换取信息或访问权限的情况并不少见。
3. 不要自行开发加密货币
这可能是密码学中最著名的规则了。它的基本含义是,你永远不应该自己编写加密算法,甚至不应该为你的项目定制新的加密算法。发明自己的密码学就像制造自己的飞机引擎。飞机引擎经历了漫长的测试过程,也经历了起起伏伏(呵呵)。同样,密码学算法也经受住了多年的考验。即使是密码学专家创建的算法,也需要经过严格的审查,经过多年的考验,才能被使用和信任。
这也适用于同一算法的不同实现。即使你在网上读过 RSA 的相关知识,并且理解其背后的数学原理,也并不意味着你的实现是安全的。流行的加密库(例如 openSSL)也经历了时间的考验,不断演进和更新,解决了所有可能存在的漏洞,其中许多漏洞你在自己实现算法时可能从未想过。即使一个算法在理论上是安全的,你实现它的方式也可能泄露一些信息。这些信息泄露可用于我们所说的侧信道攻击,这种攻击不涉及算法的理论安全性,而是涉及执行操作所需的时间,甚至是计算机发出的声音以及它所消耗的能量。
程序员在实现加密代码时,需要使用安全且最新的库(并保持更新),并为相应的算法提供正确的参数。在接下来的文章中,我们将讨论“正确的参数”究竟意味着什么。我们将看到,即使使用安全算法的安全实现,如果我们不了解自己在做什么,仍然可能犯错。上述研究检查的 26 条规则中,大多数都涉及向加密库传递不安全的参数以及使用过时的算法。
让我们学习如何避免这种情况!
文章来源:https://dev.to/shierve/cryptography-for-programmers-1-basics-block-cryptography-1iei