jwks-rsa
简介
从 JWKS(JSON Web 密钥集)端点检索密钥来生成公钥的库,其加密方式采用了非对称公钥加密算法(RSA)和非对称椭圆曲线加密算法(ECC)。
下载安装
ohpm install @ohos/jwks_rsa
OpenHarmony ohpm环境配置等更多内容,请参考 如何安装OpenHarmony ohpm包 。
使用说明
- 初始化:实例化JwksClient和设置对应的属性
this.client = new JwksClient({
jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
requestHeaders: {}, // Optional
timeout: 30000, // Defaults to 30s
cache: false,
rateLimit: true
});
},
- 获取publicKey和属性值:
公钥加密实现是使用OH子系统的加密框架(@ohos.security.cryptoFramework)。具体实现参考(https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/security/CryptoArchitectureKit/crypto-rsa-asym-encrypt-decrypt-pkcs1_oaep.md) 。
function compareRsaPubKeyBySpec(rsaKeySpec, n, e) {
if (typeof n === 'string' || typeof e === 'string') {
console.error('type is string');
return false;
}
if (typeof n === 'number' || typeof e === 'number') {
console.error('type is number');
return false;
}
if (rsaKeySpec.params.n != n) {
return false;
}
if (rsaKeySpec.pk != e) {
return false;
}
return true;
}
let n = buffer.from(key.n,'base64')
let e = buffer.from(key.e,'base64')
let bN = base64ToBigNum(n);
let eN = base64ToBigNum(e);
var commonSpec = {
algName:"RSA",
specType:cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC,
n:BigInt(bN)
}
var rsaSpec = {
algName:"RSA",
specType:cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC,
params : commonSpec,
pk :BigInt(eN),
}
//根据RSA密钥对参数生成RSA密钥对
asyKeyGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(rsaSpec);
//生成公钥实例
const pubKey = await asyKeyGenerator.generatePubKey()
//获取公钥的指定参数
let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN);
let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN);
将RSA公钥规范与预期值进行比较
if (compareRsaPubKeyBySpec(rsaSpec, nBN, eBN) != true) {
console.error("jwks_rsa error pub key big number")
} else {
console.info("jwks_rsa n, e in the pubKey are same as the spec.");
return pubKey;
}
获取publicKey和属性值
let signingKey = await this.client.getSigningKey(kid)
this.kid = signingKey.kid
this.alg = signingKey.alg
this.kty = signingKey.kty
this.use = signingKey.use
this.publicKey = await signingKey.getPublicKey()
接口说明
| 方法名 | 参数 | 接口描述 |
|---|---|---|
| JwksClient() | options: 配置对象,包含如下字段: - jwksUri(必填):用于发起 HTTP 请求的 JWKS 地址 - rateLimit(可选):是否启用速率限制 - cache(可选):是否启用缓存 - cacheMaxEntries(可选):最大缓存条目数 - cacheMaxAge(可选):缓存时间(毫秒) - jwksRequestsPerMinute(可选):每分钟最多请求次数 - requestHeaders(可选):HTTP 请求头对象 - timeout(可选):请求超时时间,默认为 30000 毫秒 |
创建一个用于从指定JWKS URI检索RSA公钥的客户端实例。 |
| getKeys() | - | 异步获取远程 JWKS 服务器返回的所有密钥数据(原始格式) |
| getSigningKeys() | - | 将所有密钥数据转换为 SigningKey 格式并返回 |
| getSigningKey() | kid: 字符串类型,表示 JWK 的唯一标识符(可为 null 或 undefined) | 根据指定的密钥 ID (kid) 获取对应的 SigningKey 对象 |
| SigningKey | - kid: 密钥的唯一标识符 - algorithm: 密钥使用的算法标识符 - type: 密钥类型标识符 - usage: 密钥用途标识符 |
表示一个可用于签名验证的公钥对象 |
| SigningKey.getPublicKey() | - | 获取当前 SigningKey 对应的公钥对象(cryptoFramework.PubKey 类型),用于后续的 JWT 验签操作 |
| ArgumentError | - | 参数错误异常,当传入参数不符合要求时抛出 |
| JwksError | - | JWKS 相关通用错误,如网络请求失败等 |
| JwksRateLimitError | - | 超出设定的请求频率限制时抛出 |
| SigningKeyNotFoundError | - | 根据 kid 查询不到对应签名密钥时抛出 |
约束与限制
在下述版本验证通过:
-
DevEco Studio 版本: 4.1 Canary(4.1.3.317)
-
OpenHarmony SDK:API11 (4.1.0.36)
目录结构
|---- OHOS_APP_jwks-rsa
| |---- entry # 示例代码文件夹
| |---- jwks-rsa # OHOS_APP_jwks-rsa库文件夹
| |---- src
|----main
|----js
|----components
|----errors
|----ArgumentError.js #错误日志
|----JwksError.js #错误日志
|----JwksRateLimitError.js #错误日志
|----SigningKeyNotFoundError.js #错误日志
|----integrations
|----config.js #支持的加密算法
|----express.js #expressJwtSecret生成秘密提供者
|----hapi.js #hapiJwtSecret生成秘密提供者
|----koa.js #koaJwtSecret生成秘密提供者
|----passport.js #passportJwtSecret生成秘密提供者
|----wrappers
|----cache.js #从缓存中获取密钥
|----callbackSupport.js #回调方法
|----interceptor.js #回调方法
|----rateLimit.js #设置请求密钥的速率
|----request.js #网路请求
|----JwksClient.js #构造方法
|----utils.js #加密算法
| |---- README.md #使用方法
| |---- README_zh.md #使用方法
关于混淆
- 代码混淆,请查看代码混淆简介
- 如果希望jwks_rsa库在代码混淆过程中不会被混淆,需要在混淆规则配置文件obfuscation-rules.txt中添加相应的排除规则:
-keep
./oh_modules/@ohos/jwks_rsa
贡献代码
使用过程中发现任何问题都可以提 Issue 给组件,当然,也非常欢迎发 PR共建 。
开源协议
本项目基于 MIT License ,请自由地享受和参与开源。