JavaScript SubtleCrypto 生成 176 位 AES 密钥而不是 128 位?

Posted

技术标签:

【中文标题】JavaScript SubtleCrypto 生成 176 位 AES 密钥而不是 128 位?【英文标题】:JavaScript SubtleCrypto generating 176-bit AES keys instead of 128-bit? 【发布时间】:2020-11-04 02:55:31 【问题描述】:

我正在开发一款游戏,该游戏将出于各种目的与 NodeJS 服务器进行通信,并且我目前正在尝试对请求有效负载实施一些 AES 加密。在服务器和用 JS 制作的测试工具之间进行测试时一切正常,但是当我尝试将客户端代码移植到另一种没有 Web Crypto / Subtle Crypto 实现的语言时,我开始收到有关 AES 密钥的错误长度。

查看它,我发现生成的 AES 密钥(通过 window.crypto.subtle.generateKey)是 176 位长,即使我指定 AES 密钥长度为 128。我正在以 JWK 格式导出密钥,而且很奇怪问题是算法被列为A128CBC,暗示它应该是128位。

因为无论如何我都会生成一个新密钥,所以我毫不犹豫地在这里发布有问题的导出 JWK:


  "alg": "A128CBC",
  "ext": true,
  "k": "J3SQ0IjwlJnJwu0EadenLg",
  "key_ops": [
    "encrypt",
    "decrypt"
  ],
  "kty": "oct"

谁能解释这些额外的 6 个字节是从哪里来的?移植客户端上的 AES 实现需要 128 位密钥,如果不是 128 则只会抛出错误,从而使整个项目停止,直到解决此问题。

【问题讨论】:

【参考方案1】:

您的 JWK 中的密钥是 base64 编码的(实际上,base64url 省略了填充)。

如果你解码 J3SQ0IjwlJnJwu0EadenLg 值,你会得到以下字节:

 27 74 90 D0 88 F0 94 99 C9 C2 ED 04 69 D7 A7 2E 

那是 16 个字节,所以是 128 位。密钥长度是正确的,您只需要在使用密钥之前添加一个额外的 base64 解码步骤。

【讨论】:

嗯。我怀疑这一点,但是当我进行 base64 解码时,我得到了 7 字节的输出......也许是因为 base64 和 base64url 之间的差异?当我学到任何东西(或成功)时,我会看看我能做些什么来解码并发布。谢谢。 啊哈!原来我使用的 base64 解码方法(内置于语言中)假设您正在解码以空字符结尾的字符串,因此当密钥解码为包含空字节时,它就坏了。我用不同的 base64 实现替换了它,它现在可以工作了!感谢您的帮助!

以上是关于JavaScript SubtleCrypto 生成 176 位 AES 密钥而不是 128 位?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript - 如何在 2020 年仅使用密码加密字符串? [复制]

前端学习笔记01JavaScript源生判断数据类型的方法

JavaScript 闭包

JavaScript:闭包

怎么爬取网页的动态内容,很多都是js动态生

加密微妙解密参数未键入“CryptoKey”