怎么通过HTML的crypto.subtle.generateKey生成对称或非对称密钥对

轻涛君_5735

轻涛君_5735

2026-05-05

690人浏览

原创

crypto.subtle.generatekey生成aes等对称密钥时,首参须为字符串(如"aes-gcm"),且必须显式指定extractable和usages;usages需匹配操作(如["encrypt","decrypt"]),密钥长度须与算法一致(如aes-256对应length: 256),extractable: true才可导出密钥。

怎么通过html的crypto.subtle.generatekey生成对称或非对称密钥对

crypto.subtle.generateKey 生成对称密钥(如 AES)

生成对称密钥时,generateKey 的第一个参数必须是字符串或对象(如 "AES-GCM"),且 extractable 和 usages 必须显式指定——漏掉任一字段会直接抛错 TypeError: Cannot create a key with no usages。

常见错误是把 usages 写成 ["encrypt", "decrypt"] 却忘了密钥长度匹配算法要求:AES-128 要 length: 128,AES-256 则必须 length: 256,传 256 却用 "AES-128-GCM" 会失败。

  • extractable 设为 true 才能用 subtle.exportKey() 拿到原始字节;设 false(默认)则密钥只能在 SubtleCrypto 内部使用
  • usages 必须严格匹配后续操作:比如只写 ["encrypt"],之后调 decrypt() 就报 OperationError
  • AES 密钥不支持 namedCurve 或 modulusLength,这些是给非对称算法用的,混用会静默失败或抛 DataError
const aesKey = await crypto.subtle.generateKey("AES-GCM", true, ["encrypt", "decrypt"]);
// ✅ 正确:算法名字符串 + extractable + 完整 usages

crypto.subtle.generateKey 生成非对称密钥对(如 RSA、ECDSA)

RSA 和 ECDSA 的调用结构完全不同:它们必须传入一个对象参数,含 name、modulusLength(RSA)或 namedCurve(ECC),且 usages 要分别指定给 publicKey 和 privateKey——很多人只写一个 usages 数组,结果 publicKey 没法 verify,privateKey 不能 sign。

RSA 最小 modulusLength 是 2048,设 1024 会抛 OperationError;ECC 的 namedCurve 只接受标准值如 "P-256"、"P-384",写 "secp256r1" 或大小写错误(如 "p-256")全都不行。

  • RSA 密钥对中,publicKey.usages 通常为 ["verify"],privateKey.usages 为 ["sign"];加密场景则反过来用 ["encrypt"]/["decrypt"]
  • ECC 不支持 modulusLength,传了会忽略或报错;RSA 不支持 namedCurve,写了就失效
  • extractable 只控制 privateKey 是否可导出;publicKey 总是可导出的(只要 extractable: true)
const rsaKeys = await crypto.subtle.generateKey(
  { name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
  true,
  { publicKey: ["encrypt"], privateKey: ["decrypt"] }
);

为什么 generateKey 返回的是 Promise 或 Promise

返回类型取决于算法:对称算法(AES、HMAC)返回 Promise<cryptokey></cryptokey>,因为只生成单个密钥;非对称算法(RSA、ECDSA、Ed25519)返回 Promise<cryptokeypair></cryptokeypair>,包含 publicKey 和 privateKey 两个属性。混淆这两者会导致解构错误,比如对 AES 结果写 const { publicKey } = await generateKey(...),结果 publicKey 是 undefined。

Crypto Funding Harvester
Crypto Funding Harvester

扫描Hyperliquid、Binance和Bybit的永续合约资金费率,识别Delta中性套利机会。Delta中性套利交易...

下载

另一个坑是没等 Promise settle 就直接传给 encrypt() 或 sign()——这些 API 不接受 Promise,只认 CryptoKey 实例,必须用 await 或 .then() 解包。

  • 判断类型可用 key instanceof CryptoKey(对称)或 keyPair instanceof CryptoKeyPair(非对称)
  • ECDSA 和 Ed25519 的 usages 不支持 ["encrypt"] 或 ["decrypt"],只允许签名/验签相关操作
  • 浏览器兼容性要注意:"Ed25519" 在 Safari 16.4+ 才支持,旧版会抛 NotSupportedError

导出密钥时 exportKey 报错 “InvalidAccessError”

这个错误几乎都源于密钥创建时 extractable 设成了 false(或没传,默认 false)。一旦密钥不可提取,后续任何 exportKey("jwk")、exportKey("raw") 都会立刻失败,且无法补救——密钥对象本身不可变。

还有种情况是导出格式和密钥类型不匹配:比如用 "spki" 格式导出 AES 密钥(只支持 RSA/EC 公钥),或用 "pkcs8" 导出公钥(它只用于私钥)。这些都会触发 DataError,而不是 InvalidAccessError,但初学者容易混淆。

  • 对称密钥只能用 "raw" 或 "jwk" 导出;"spki" 和 "pkcs8" 仅限非对称密钥
  • ECDSA 公钥用 "spki",私钥用 "pkcs8";RSA 两者都支持,但格式内容不同
  • 导出 JWK 时,extractable: false 的密钥仍可导出,但 k 字段为 null(对称)或缺失 d(私钥)

最稳妥的做法:生成时就明确设 extractable: true,除非你确定密钥永远只在 SubtleCrypto 内部流转。

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!

相关文章

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

html crypto

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

3189

3

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

2023.07.25

2308

9

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

2023.08.02

1260

5

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.09

1198

4

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

2023.09.05

1356

5

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2178

7

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

2023.09.20

3480

8

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

2023.09.22

15895

6

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
GDB 17.2 官方文档集合
GDB 17.2 官方文档集合

共0课时 | 0人学习

Bootstrap 入门安装配置
Bootstrap 入门安装配置

共0课时 | 0人学习

38+ PhpStorm 提示和技巧
38+ PhpStorm 提示和技巧

共1课时 | 224人学习