libsodium 为 AES-GCM 提供“is_available()”API 的原因是,与 OpenSSL 不同,libsodium 不会公开 AES-GCM,除非您的处理器支持硬件加速的 AES 和 PCLMULQDQ 指令。
如果您想知道这意味着什么:软件 AES 容易受到缓存计时攻击,因为它内部依赖于表查找:https://cr.yp.to/antiforgery/cachetiming-20050414.pdf (PDF)
GCM 中的认证步骤也有类似的攻击(根据上下文称为 GMAC 或 GHASH),它会泄露 GHASH 密钥(称为 H)并可用于自由执行选择密文攻击。
- 您可以在此处了解有关 GCM 漏洞的更多信息(在非计时泄露而是重复使用 nonce 的情况下,但结果相同):https://www.youtube.com/watch?v=uxuXFK5XKEU
- 您可以在此处了解有关 AES-GCM 的更多信息:https://soatok.blog/2020/05/13/why-aes-gcm-sucks/
- 您可以在此处了解它与其他加密模式的比较方式:https://soatok.blog/2020/07/12/comparison-of-symmetric-encryption-methods/
其他 AEAD 模式在软件中实现是安全的,不会出现侧信道泄露风险。
需要注意的是:AES-GCM 并非在所有硬件上都保证可用,因为如果没有硬件支持,libsodium 不会提供不安全的实现。
如果您想要即使在您无法控制的硬件上也能保证可用的东西(您好,开源维护者),您的选择是 ChaCha20-Poly1305 和 XChaCha20-Poly1305。
如果您能够控制硬件并明确需要 AES-GCM(注意,用于 FIPS 140-2 验证),请随意使用 AES-256-GCM。
<?php
function do_something(string $message, CryptoKeyObject $key): string {
if (!sodium_crypto_aead_aes256gcm_is_available()) {
throw new Exception("AES-256-GCM isn't available on your hardware");
}
// ... 您的代码在此处 ...
}
?>