Daily Tech Briefing
AI 科技速览

每天 5 分钟内学习 AI。获取最新的人工智能新闻,理解其重要性,并学习如何将其应用于您的工作。

AI 快讯
Dev.to AI · 2026/8/1 09:00:32

Nobody Writes Bad Crypto. They Write Correct Crypto at Four Layers.

AI 中文解读
这篇文章揭露了一个反直觉的现象:程序员很少写出“明显错误”的加密代码,真正的漏洞往往藏在看起来完全正确的外表下。作者把密码学问题拆成四个隐蔽层次:第一层是用错工具类型,比如该用加密哈希却用了普通随机数;第二层是选错加密模式,AES加密算法看着高级,但用了ECB模式就像给图片盖了层透明纸,加密后还能看出原图;第三层是参数错误,比如用固定不变的初始化向量,或者用了过时的填充方式,这些细节往往是一行常量,很难引起注意;第四层更隐蔽,连加密本身都是对的,却在后续代码里把密钥打印出来,或者用不安全的比较方式泄露了信息。 最反直觉的是,越重视安全、越有经验的团队,反而越容易栽在三四层。因为他们花大力气升级了算法,却以为高枕无忧,不再检查更深的漏洞。对普通人来说,这意味着即便你的密码学技术再先进,真正决定安全的是整个系统的每个环节。未来,企业做安全审计时,不能只盯着“用了什么算法”,还得专门排查参数和使用逻辑,才能避免“金库大门焊死了,窗户却开着”的尴尬。
<p>The code review comment I have written most often, and regretted most often, is<br> "use a stronger algorithm."</p> <p>It is regrettable because it is almost never the actual defect. It is the defect I can see<br> from where I am standing. The team swaps SHA-1 for SHA-256, everyone agrees the review was<br> useful, and the thing that would have mattered stays where it was.</p> <h2> Four layers, each hiding the next </h2> <p>A crypto call has to be right four separate times, and being correct at one layer makes<br> the next one invisible. AES looks like a decision you already made. It is four.</p> <p><strong>Layer 1 — the primitive.</strong> {#layer-1} Right kind of thing? A hash where you needed a<br> KDF. A cipher where you needed a MAC. <code>Math.random()</code> where you needed a CSPRNG. Everyone<br> reviews this layer, because it is visible in the function name.</p> <p><strong>Layer 2 — the mode.</strong> {#layer-2} Primitive right, mode wrong. AES in ECB encrypts<br> identical blocks to identical ciphertext — which is why the famous penguin is still<br> legible after "encryption." Nothing about <code>aes-256-ecb</code> reads as wrong at a glance; it<br> contains <code>aes</code> and <code>256</code>, and both are reassuring.</p> <p><strong>Layer 3 — the parameters.</strong> {#layer-3} Right primitive, right mode, wrong inputs. A<br> static IV. An iteration count set in 2015 and never revisited. RSA where someone passed<br> <code>RSA_PKCS1_PADDING</code> explicitly — Node defaults to OAEP, so this one takes a deliberate<br> argument to get wrong, which is exactly why it survives review. Each is a single value,<br> usually a constant, and constants do not attract attention.</p> <p><strong>Layer 4 — the usage.</strong> {#layer-4} Everything above correct, and the surrounding code<br> gives it away. Comparing an HMAC with <code>===</code> and leaking the answer through timing.<br> Deriving a key correctly, then logging it. This layer is not crypto code at all, which is<br> why crypto review misses it.</p> <h2> Why layers beat a rule list </h2> <p>A rule list tells you what to grep for. The layer tells you where your team is, and<br> therefore what you are <em>not</em> going to catch.</p> <p>My working hypothesis — and it is a hypothesis, not something I have measured — is that<br> failures cluster by how much crypto attention a team has already had. Never thought about<br> it: layer 1. Just audited: layer 2, because the audit said "upgrade the primitives" and it<br> did exactly that. Careful for years: layers 3 and 4.</p> <p>If that holds, the uncomfortable corollary is that layer 3 and 4 defects live longest<br> <em>because</em> the code passes every review asking "are we using strong algorithms." The<br> maturity that fixes the first two layers is the same maturity that stops looking further<br> down. That is the measurement I most want from this taxonomy.</p> <h2> Detection: the easy layers are the trap </h2> <p>Layers 1 and 2 live in a single call expression. <code>createHash("sha1")</code> and <code>aes-256-ecb</code><br> are string literals; matching them is syntactic and any linter does it well.</p> <p>Layers 3 and 4 are not. Whether an IV is static depends on where it came from — a<br> data-flow question, the difference between<br> <a href="https://ofriperetz.dev/go/taint-vs-heuristic-detection?utm_source=devto&amp;from=crypto-misuse-taxonomy" rel="noopener noreferrer">matching a pattern and following a value</a>.<br> Whether a comparison is timing-unsafe depends on whether the value is a secret, which no<br> analyzer knows from the expression alone.</p> <p>So tool coverage is inversely correlated with how long a defect survives. The layers a<br> tool covers cleanly are the ones your team already fixes. Read any claim that a tool<br> "covers crypto" as "covers layers 1 and 2" until shown otherwise — and checking that needs<br> <a href="https://ofriperetz.dev/go/ground-trut
分享
阅读原文