window.crypto.subtle.encrypt 对 AES-CBC 使用什么填充

Tac*_*yon 6 javascript encryption

我目前正在使用window.crypto.subtle.encryptJavascript 中的网络加密 API 。我的问题是,默认情况下使用什么填充?我已经搜索了一段时间,但找不到任何答案。

Maa*_*wes 6

Subtle.encrypt似乎正在实施 WebCrypto。虽然文档encrypt()例如 Mozilla 的 CBC 模式没有显示填充。引用的 NIST 规范也没有。

幸运的是,引用的 WebCrypto API确实指示了指定 CBC 模式的填充:

在 CBC 模式下运行时,可以在各种填充方案下填充不是 AES 块大小(16 字节)的精确倍数的消息。在 Web Crypto API 中,唯一支持的填充模式是 PKCS#7,如 [RFC2315] 的第 10.3 节第 2 步所述

如果您点击链接,您会发现 PKCS#7 是加密消息语法或 CMS 的规范。但是,只指定了一种填充模式。此模式没有比 PKCS#7 填充更具体的名称(ECB 和 CBC 的填充算法非常简单,因此通常不会获得特定名称)。


简单地说,它为 AES 等块大小为 128 位的密码增加了 1 到 16 个字节。字节值与填充的字节数相同,因此您可以通过删除最后一个字节指示的尽可能多的字节来取消填充。因此,填充始终是,即使明文的最后一部分是完整的(在这种情况下应用了 16 个字节的填充),也应用填充。

所以你会有

10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 // empty, zero byte message
PT 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F // PT means plaintext byte
PT PT 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E // byte values in hexadecimals
...

PT PT PT PT PT PT PT PT PT PT PT PT PT PT PT 01 // 15-byte message
// 16-byte message, one full block of padding added
PT PT PT PT PT PT PT PT PT PT PT PT PT PT PT PT 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 
...
...
Run Code Online (Sandbox Code Playgroud)

请注意,填充不应用于验证明文的正确性,填充预言机攻击(使用 GCM 等身份验证模式代替!),填充值可能无法全部验证(最后一个字节包含足够的信息以取消填充)和最后,您应该使用一个实现来验证填充字节是否在指定的范围内。

另请注意,AES 的 PKCS#7 填充有时会被错误地(或懒惰地)称为 PKCS#5 填充,例如在 Java JCA 中。