Forge:web端与 Node.js 安全开发中的加密与网络通信工具集,支持哈希、对称 / 非对称加密及 TLS 实现

Forge:web端与 Node.js 安全开发中的加密与网络通信工具集,支持哈希、对称 / 非对称加密及 TLS 实现

夸克资源分享:

表情包:https://pan.quark.cn/s/5b9ddeb237fe

工具箱:https://pan.quark.cn/s/aa2d6a730482,图吧、美蛋、路遥、入梦等

Fiddler Everywhere抓包:https://pan.quark.cn/s/6b1e2fbae019

Adobe:https://pan.quark.cn/s/13e39cfeaadb,先看安装教程

JetBranis开发者工具:https://pan.quark.cn/s/16e94dcff1f7,先看安装教程下的jetbra教程

逆向工具:https://pan.quark.cn/s/50e93c8ca54c

数据库工具:https://pan.quark.cn/s/2f14eda13d24

kettle:https://pan.quark.cn/s/62f320634c75

前端项目搭建集锦:https://blog.csdn.net/randy521520/article/details/146998467
前端接单》前端接单 》前端接单: https://www.goofish.com/item?id=1008883794643

一、简介

前端 forge 库是一个专注于加密技术与网络通信的 JavaScript 开源库,提供了原生 TLS(传输层安全)实现及一系列加密相关工具,专为构建加密密集型、网络依赖型 Web 应用设计,在密码学处理、安全通信等场景中具有广泛应用,Git链接:https://gitcode.com/gh_mirrors/for/forge?source_module=search_project

1.全面的加密算法支持:涵盖多种主流加密相关算法与标准,包括 MD5、SHA1、SHA256 等哈希算法,丰富的对称 / 非对称加密方案,以及 PKCS 系列标准(PKCS1、PKCS7、PKCS12 等),可满足证书处理、数据加密解密、数字签名等核心安全需求。

2.原生 TLS 实现:内置 JavaScript 原生 TLS 协议支持,无需依赖额外底层环境,助力 Web 应用实现安全的网络数据传输,保障通信过程的保密性与完整性。

3.实用工具集:提供加密相关辅助工具,例如证书管理、数据编解码、加密参数配置等,适配 Web 应用开发中各类安全相关场景,降低加密功能开发门槛。

二、安装

javascript 复制代码
yarn add node-forge
yarn add @types/node-forge --dev

三、哈希加密

javascript 复制代码
import forge from 'node-forge';

let message = 'hello world!';

let sha1 = forge.md.sha1.create();
sha1.update(message);
console.log('sha1:',sha1.digest().toHex());

let sha256 = forge.md.sha256.create();
sha256.update(message);
console.log('sha256:',sha256.digest().toHex());


let sha384 = forge.md.sha384.create();
sha384.update(message);
console.log('sha384:',sha384.digest().toHex());

let sha512 = forge.md.sha512.create();
sha512.update(message);
console.log('sha512:',sha512.digest().toHex());

let md5 = forge.md.md5.create();
md5.update(message);
console.log('md5:',md5.digest().toHex());


let hmac = forge.hmac.create();
hmac.start('sha1', 'Jefe');
hmac.update( message);
console.log('hmac:',hmac.digest().toHex());

四、AES对称加密

1.支持AES-ECB、AES-CBC、AES-CFB、AES-OFB、AES-CTR、AES-GCM

加密模式 核心特性 优点 缺点 适用场景 不适场景
AES-ECB 电子密码本模式,相同明文加密结果相同;分组独立加密 1. 算法简单,运算速度最快; 2. 无需维护IV,实现成本低; 3. 支持并行加密/解密(分组独立) 1. 安全性极差,易暴露明文规律(如重复明文对应重复密文); 2. 无完整性校验,密文易被篡改; 3. 无法隐藏明文结构(如图片加密后仍能看到轮廓) 1. 加密少量无规律的固定数据(如密码本身的加密存储); 2. 对安全性要求极低的测试场景; 3. 作为其他加密模式的底层辅助 1. 传输类数据(如接口请求、文件传输); 2. 敏感数据(如密码、金融信息); 3. 大量重复明文数据
AES-CBC 密码分组链接模式,需16字节IV;前一分组密文参与后一分组加密 1. 安全性优于ECB,相同明文加密结果不同; 2. 兼容性极强,几乎所有加密库都支持; 3. 实现简单,部署成本低 1. 不支持并行加密(需依赖前一分组结果); 2. 无内置完整性校验,需额外添加哈希校验(如SHA256); 3. IV若泄露或重复,会降低安全性; 4. 密文一位篡改会导致后续分组明文乱码 1. 传统系统的兼容性加密(如老旧项目数据存储); 2. 对性能要求不高的静态数据加密(如本地配置文件加密); 3. 非实时性的数据备份加密 1. 高并发实时通信(如视频流、即时消息); 2. 需并行处理的大规模数据加密; 3. 对完整性要求极高的金融场景
AES-CFB 密文反馈模式,需IV;将前一分组密文加密后与明文异或得到密文;支持按位/按字节加密 1. 无需对明文进行分组填充(支持任意长度明文); 2. 安全性优于CBC,密文篡改影响范围小; 3. 可实现流式加密(适合分段传输数据) 1. 不支持并行加密(依赖前一分组结果); 2. 加密速度慢于CBC; 3. 无内置完整性校验,需额外校验; 4. 解密需依赖加密时的反馈状态,断流后需重新同步 1. 流式数据加密(如串口通信、分段传输的文件); 2. 需处理非固定长度明文的场景(如实时日志加密); 3. 网络不稳定的远程数据传输 1. 高并发批量数据加密; 2. 对速度要求极高的场景; 3. 需完整性自动校验的敏感场景
AES-OFB 输出反馈模式,需IV;将加密器输出的伪随机流与明文异或得到密文;分组独立生成伪随机流 1. 无需对明文分组填充(支持任意长度明文); 2. 支持并行解密(伪随机流独立生成); 3. 密文一位篡改仅导致明文对应位错误,影响范围小; 4. 适合流式传输,断流后恢复简单 1. 不支持并行加密(伪随机流生成依赖前一分组); 2. 无内置完整性校验,易被篡改; 3. 伪随机流若泄露,明文可被还原; 4. 加密速度慢于CBC 1. 实时流式数据传输(如音频、视频流加密); 2. 网络不稳定的远程数据交互(如卫星通信); 3. 需分段解密的大型文件 1. 高并发批量数据加密; 2. 对完整性要求极高的金融、涉密场景; 3. 对加密速度要求严苛的场景
AES-CTR 计数器模式,需IV(计数器初始值);通过计数器生成伪随机流,与明文异或得到密文 1. 支持并行加密/解密(计数器独立,伪随机流可并行生成); 2. 无需明文分组填充(支持任意长度明文); 3. 加密和解密使用同一套逻辑(仅计数器递增方式不同); 4. 安全性高,密文无规律; 5. 适合流式数据,断流后可通过计数器偏移恢复 1. 无内置完整性校验,需额外添加校验机制; 2. 计数器若被篡改,会导致后续明文全部乱码; 3. IV(计数器初始值)需唯一,不可重复使用 1. 高并发实时通信(如即时消息、视频会议流); 2. 大规模数据并行处理(如云存储文件加密); 3. 流式数据传输(如物联网设备数据上报); 4. 对性能要求较高的分布式系统 1. 对完整性要求极高且无法额外添加校验的场景; 2. 计数器易被篡改的不安全环境; 3. 老旧不支持并行处理的系统
AES-GCM 伽罗瓦/计数器模式,AEAD认证加密模式;需12/16字节IV;支持additionalData;内置认证标签(Tag) 1. 一站式实现"加密+完整性校验+身份认证",安全性最高; 2. 支持并行加密/解密(基于CTR模式扩展); 3. 无需明文分组填充,支持任意长度明文; 4. 可传递附加认证数据(AAD),验证关联元数据; 5. 加密效率高,兼顾安全与性能 1. 实现复杂度高于非AEAD模式; 2. 对IV唯一性要求极高(重复IV会导致密钥泄露); 3. 部分老旧加密库不支持; 4. 认证标签需随密文一起传输,增加少量数据开销 1. 高安全要求的敏感数据传输(如金融交易、支付接口); 2. 物联网设备通信(如智能家居、工业设备数据加密); 3. 安全文件传输(如涉密文档、备份文件); 4. 接口加密(如前后端、微服务之间的通信); 5. 需验证元数据完整性的场景 1. 兼容性要求极高的老旧系统; 2. 对加密复杂度敏感的极简设备(如低端嵌入式设备); 3. 对安全性要求极低的测试场景
1. 安全性排序(从低到高):AES-ECB < AES-CBC < AES-CFB ≈ AES-OFB < AES-CTR < AES-GCM 2. 性能排序(从快到慢):AES-ECB > AES-CBC > AES-CTR ≈ AES-GCM > AES-OFB > AES-CFB 3. 核心选型原则: • 优先选择AES-GCM:绝大多数现代场景的最优解,兼顾安全、性能和功能完整性; • 兼容老旧系统选AES-CBC:兼容性最强,需额外添加哈希校验弥补完整性缺陷; • 实时流式传输选AES-CTR/AES-OFB:支持并行处理或断流恢复,适合音视频、物联网数据; • 绝对避免AES-ECB:仅用于极低安全要求的边缘场景,不可用于敏感数据处理。

2.AES-ECB加密(AES-128)

javascript 复制代码
import forge from 'node-forge';

//密钥大小将决定使用 16 字节(AES-128)、24 字节(AES-192)或 32 字节(AES-256)
let key = forge.random.getBytesSync(16);
let iv = forge.random.getBytesSync(16);
let message = 'hello world!';

//支持AES-ECB、AES-CBC、AES-CFB、AES-OFB、AES-CTR、AES-GCM
let cipher = forge.cipher.createCipher('AES-ECB', key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer(message));
cipher.finish();
let encrypted = cipher.output;
let encryptedHex = encrypted.toHex();

console.log('加密结果:', encryptedHex);

let decipher = forge.cipher.createDecipher('AES-ECB', key);
decipher.start({ iv: iv });
decipher.update(forge.util.createBuffer(forge.util.hexToBytes(encryptedHex)));
decipher.finish();

console.log('解密结果:', decipher.output.toString());

3.AES-CBC加密(AES-192)

javascript 复制代码
import forge from 'node-forge';

let message = 'hello world!';
const sha256 = forge.md.sha256.create();
sha256.update(message);
console.log(sha256.digest().toHex());

//密钥大小将决定使用 16 字节(AES-128)、24 字节(AES-192)或 32 字节(AES-256)
let key = forge.random.getBytesSync(24);
let iv = forge.random.getBytesSync(16);


//支持AES-ECB、AES-CBC、AES-CFB、AES-OFB、AES-CTR、AES-GCM
let cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer(`${message},${sha256.digest().toHex()}`));
cipher.finish();
let encrypted = cipher.output;
let encryptedHex = encrypted.toHex();

console.log('加密结果:', encryptedHex);

let decipher = forge.cipher.createDecipher('AES-CBC', key);
decipher.start({ iv: iv });
decipher.update(forge.util.createBuffer(forge.util.hexToBytes(encryptedHex)));
decipher.finish();

console.log('解密结果:', decipher.output.toString().split(',')[0]);

4.AES-GCM加密(AES-256)

javascript 复制代码
import forge from 'node-forge';

//密钥大小将决定使用 16 字节(AES-128)、24 字节(AES-192)或 32 字节(AES-256)
let key = forge.random.getBytesSync(32);
let iv = forge.random.getBytesSync(16);
let message = 'hello world!';

//支持AES-ECB、AES-CBC、AES-CFB、AES-OFB、AES-CTR、AES-GCM
let cipher = forge.cipher.createCipher('AES-GCM', key);
cipher.start({
    iv: iv,
    additionalData: '附加数据',
    tagLength: 128
});
cipher.update(forge.util.createBuffer(message));
cipher.finish();
let encrypted = cipher.output;
let encryptedHex = encrypted.toHex();

console.log('加密结果:', encryptedHex);

let decipher = forge.cipher.createDecipher('AES-GCM', key);
decipher.start({
    iv: iv,
    additionalData: '附加数据',
    tagLength: 128,
    tag: cipher.mode.tag
});
decipher.update(forge.util.createBuffer(forge.util.hexToBytes(encryptedHex)));
decipher.finish();

console.log('解密结果:', decipher.output.toString());

5.分块加密,适合长密文

javascript 复制代码
import forge from 'node-forge';

let key = forge.random.getBytesSync(16);
let iv = forge.random.getBytesSync(16);

const originalPlainText = `
时间是一个智者,不疾不徐地告诉我三个"最"。经历的越多,我就越能明白时间想要告诉我的"最"是什么。我想要寻找的是长远、安心和温暖,时间指引着我寻找它们。
一、最长远的是简单
很多东西一旦变得复杂了,就会让人觉得索然无味,即使之前再怎么喜欢,也会很快失去兴趣,然后去寻找下一件能够让自己喜欢的东西。但是在这个最不缺改变的世界中,简单也许是稀缺品。越是稀缺,我们越是珍惜,想方设法守护这份简单,让简单一直延续下去。
就像友情,我最好的朋友都是在学生时代结交的,而进入职场后交到的朋友大多都是泛泛之交。因为在校园里,我们没有太多的利益冲突,只要臭味相投,都可 这样的友谊相对来说比较简单,往往能够长久。当进入激烈的社会竞争中,大家都有个人的利益追求,友谊有时候就是利益的踏板,真诚的成分有多少大家心中有数。当没有利用价值了,这样的友谊往往名存实亡。
二、最安心的是平凡的陪伴
虽然大家都在努力地工作赚钱,觉得有车、有房、有存款才有安全感,但是物质上的满足带来的安全感只是表面的、暂时的。人最高的需求并不在于物质,而在于精神,精神上得到的满足远比物质上得到的满足来得更持久、更安心。最令人安心的是平凡的陪伴,无论富有或是贫穷,无论貌美或平凡,都能陪伴在自己身边。在这样的陪伴下,心就能安定下来了。不需要担心任何事情,因为你知道对方一定会陪着你面对所有事情,就像多了一个坚实的后盾,和你不离不弃。
三、最温暖的是懂得
随着阅历的增加,你懂得越多,能懂你的人就越少,因为你已经习惯理解别人,却不是每个人都能同样理解你的酸甜苦辣。当你受到太多来自世界的薄情时,你最渴望的大概就是一份真正的懂得吧。这份懂得, 因为你知道,就算全世界都不理解你也没有关系,只要有一个人懂你就足够了。你会明白你需要的不是所有人的理解,仅仅需要一份真心的懂得。成功了,别人只会看到你的风光,但只有懂你的人才会知道你付出了多少;失败了,别人只会嘲笑你的无能,但只有懂你i的人才会鼓励你不要放弃。最温暖的是懂得,它会给予你勇气和信心。
时间告诉我三个"最":最长远的是简单,最安心的是平凡的陪伴,最温暖的是懂得。我认为人活一世,最需要的正是长远、安心和温暖。时间把方向告诉了我,我会朝着这个方向寻找。也许要用一辈子的时间,才能得到,但是我相信在这个寻找的过程中,我也会得到快乐和成长,这大概也是时间给我的赠礼吧。
`;
const plainTextBytes = forge.util.encodeUtf8(originalPlainText);

let cipher = forge.cipher.createCipher('AES-CFB', key);
cipher.start({ iv: iv });
let length = plainTextBytes.length;
let chunkSize = 1024;
let index = 0;
do {
    let buf = forge.util.createBuffer(plainTextBytes.slice(index, index + chunkSize));
    cipher.update(buf);
    index += chunkSize;
} while(index < length);
cipher.finish();

const encrypted = cipher.output; // 加密后的缓冲区
const encryptedBytes = encrypted.bytes(); // 密文字节串

//分块解密
let decryptIndex = 0;
const decipher = forge.cipher.createDecipher('AES-CFB', key);
decipher.start({ iv: iv });
do {
    const currentDecryptChunk = encryptedBytes.slice(decryptIndex, decryptIndex + chunkSize);
    const buf = forge.util.createBuffer(currentDecryptChunk);
    decipher.update(buf);
    decryptIndex += chunkSize;
} while (decryptIndex < encryptedBytes.length);
decipher.finish();

console.log('==============解密结果==============');
console.log(decipher.output.toString());

6.加密对象:forge.cipher.createCipher(algorithm, payload)、解密对象:decipher = forge.cipher.createDecipher(algorithm, payload),返回BlockCipher对象

属性 类型 参数说明 返回值 / 属性值说明 详细说明
start Function options: 可选, 类型为StartOptions, 是加密/解密的启动配置项, 包含: iv(初始向量) tag(认证标签) tagLength(标签长度) additionalData(附加认证数据) 等属性 无返回值 用于启动加密或解密流程, 必须在update方法之前调用, 传入的配置项需与加密/解密模式匹配(如GCM模式需传入tag, CBC模式需传入iv)
update Function payload: 必传, 类型为util.ByteStringBuffer, 是待加密的明文缓冲区或待解密的密文缓冲区, 支持分块传入 无返回值 用于处理待加密/解密的数据, 可多次分块调用(适合处理大文本、大文件等海量数据), 数据会逐步处理并写入output属性
finish Function 无参数 布尔(boolean): true表示加密/解密流程完全成功; false表示流程失败(常见原因: 密钥不匹配、IV错误、密文被篡改、模式配置异常) 用于完成最终的加密/解密处理, 包括数据填充补全、认证校验等收尾操作, 调用后才能获取完整的output结果
output util.ByteStringBuffer - 详情见文章中的"util.ByteStringBuffer" 存储加密后的完整密文或解密后的完整明文, 为forge专属缓冲区类型, 可通过bytes()转为字节串、toHex()转为十六进制字符串、toString()转为普通文本
mode Mode - mode.tag: util.ByteStringBuffer 存储加密/解密的模式专属对象, 该对象实现了Mode接口, 包含模式特有属性(如GCM模式下的tag认证标签), 仅用于获取模式相关的附加数据

五、DES对称加密

1.支持3DES-ECB、3DES-CBC、DES-ECB、DES-CBC

加密算法 核心特性 优点 缺点 适用场景 不适用场景
3DES-ECB 3重DES(168位密钥)+ 电子密码本模式;无IV,相同明文加密结果相同;分组独立加密 1. 密钥长度(168位)比DES安全; 2. 算法简单,运算速度较快; 3. 支持并行加密/解密 1. ECB模式安全性弱,易暴露明文规律; 2. 无完整性校验,密文易被篡改; 3. 加密效率低于AES 1. 老旧系统兼容场景(需替换DES但无法升级AES); 2. 对安全性要求不高的历史数据加密 1. 新系统开发(优先选AES); 2. 敏感数据(如金融、隐私信息); 3. 大量重复明文数据
3DES-CBC 3重DES + 密码分组链接模式;需8字节IV;前一分组密文参与后一分组加密 1. 安全性优于3DES-ECB,相同明文加密结果不同; 2. 兼容性强,老旧加密库普遍支持; 3. 比DES更抗暴力破解 1. 不支持并行加密; 2. 无内置完整性校验; 3. 加密效率低(比AES慢数倍); 4. IV若重复会降低安全性 1. 老旧金融/通信系统的历史数据加密; 2. 需兼容早期3DES协议的场景 1. 高并发/高性能场景; 2. 新系统开发; 3. 大体积数据加密
DES-ECB DES(56位密钥)+ 电子密码本模式;无IV,分组独立加密 1. 算法最简单,运算速度快; 2. 实现成本极低,兼容性极强 1. 密钥长度过短(56位),易被暴力破解; 2. ECB模式安全漏洞大,明文规律易暴露; 3. 已被密码学标准淘汰 1. 仅用于极低安全要求的历史遗留系统(无替代方案时); 2. 测试/演示场景 1. 所有实际生产场景; 2. 任何敏感数据处理; 3. 新系统开发
DES-CBC DES + 密码分组链接模式;需8字节IV;分组依赖前一分组密文 1. 安全性略优于DES-ECB; 2. 兼容性极强,早期系统广泛支持 1. 密钥长度过短(56位),安全风险极高; 2. 加密效率低,且无完整性校验; 3. 已被现代密码学标准废弃 1. 仅用于无法升级的远古遗留系统(迫不得已时) 1. 所有生产环境; 2. 敏感数据场景; 3. 新系统/新功能开发
1. 安全性排序:3DES-CBC > 3DES-ECB > DES-CBC > DES-ECB 2. 性能排序:DES-ECB > DES-CBC > 3DES-ECB > 3DES-CBC 3. 选型原则: • 优先避免使用DES/3DES,现代场景必须选AES; • 仅在老旧系统兼容时使用3DES(优先选3DES-CBC); • 绝对禁止在新系统中使用DES(已完全不安全)。

2.3DES-CBC加密

javascript 复制代码
import forge from 'node-forge';

//密钥大小将决定使用 24 字节(3DES-CBC、3DES-ECB)
let key = forge.random.getBytesSync(24);
let iv = forge.random.getBytesSync(8);
let message = 'hello world!';

//支持3DES-ECB、3DES-CBC、DES-ECB、DES-CBC
let cipher = forge.cipher.createCipher('3DES-CBC', key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer(message));
cipher.finish();
let encrypted = cipher.output;
let encryptedHex = encrypted.toHex();

console.log('加密结果:', encryptedHex);

let decipher = forge.cipher.createDecipher('3DES-CBC', key);
decipher.start({ iv: iv });
decipher.update(forge.util.createBuffer(forge.util.hexToBytes(encryptedHex)));
decipher.finish();

console.log('解密结果:', decipher.output.toString());

3.DES-ECB加密

javascript 复制代码
import forge from 'node-forge';

//密钥大小将决定使用 8 字节(DES-ECB、DES-CBC)
let key = forge.random.getBytesSync(8);
let iv = forge.random.getBytesSync(8);
let message = 'hello world!';

//支持3DES-ECB、3DES-CBC、DES-ECB、DES-CBC
let cipher = forge.cipher.createCipher('DES-ECB', key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer(message));
cipher.finish();
let encrypted = cipher.output;
let encryptedHex = encrypted.toHex();

console.log('加密结果:', encryptedHex);

let decipher = forge.cipher.createDecipher('DES-ECB', key);
decipher.start({ iv: iv });
decipher.update(forge.util.createBuffer(forge.util.hexToBytes(encryptedHex)));
decipher.finish();

console.log('解密结果:', decipher.output.toString());

六、ED25519数字签名

ED25519基于椭圆曲线的数字签名算法,其密钥长度为 256 位,签名长度为 64 字节。

优点

  • 运算速度远快于 RSA;
  • 密钥 / 签名长度短,传输、存储成本低;
  • 安全性高,具备抗量子攻击的潜力。

缺点

  • 兼容性弱于 RSA,部分老旧系统不支持;
  • 仅支持签名、验签操作,不支持加密、解密功能。

适用场景

  • 现代应用的数字签名场景,比如区块链、API 接口身份认证;
  • 移动设备、物联网等轻量级安全场景。

1.普通消息签名

javascript 复制代码
import forge from 'node-forge';

let ed25519 = forge.pki.ed25519;

let password = 'Mai9ohgh6ahxee0jutheew0pungoozil';
const seed = forge.util.encodeUtf8(password);
let keypair = ed25519.generateKeyPair({ seed: seed });

let signature = ed25519.sign({
    message: 'hello world!',
    encoding: 'utf8',
    privateKey: keypair.privateKey
});

let verify = ed25519.verify({
    message: 'hello world!',
    encoding: 'utf8',
    publicKey: keypair.publicKey,
    signature: signature
});
if (verify) {
    console.log('🎉 验签通过!消息未被篡改,签名合法有效');
} else {
    console.error('❌ 验签失败!消息已被篡改或签名不合法');
}

2.二进制数据签名

javascript 复制代码
import forge from 'node-forge';

let ed25519 = forge.pki.ed25519;

let password = 'Mai9ohgh6ahxee0jutheew0pungoozil';
const seed = forge.util.encodeUtf8(password);
let keypair = ed25519.generateKeyPair({ seed: seed });

let signature = ed25519.sign({
    message: Buffer.from('hello world!', 'utf8'),
    privateKey: keypair.privateKey
});

let verify = ed25519.verify({
    message: Buffer.from('hello world!', 'utf8'),
    publicKey: keypair.publicKey,
    signature: signature
});
if (verify) {
    console.log('🎉 验签通过!消息未被篡改,签名合法有效');
} else {
    console.error('❌ 验签失败!消息已被篡改或签名不合法');
}

3.哈希签名

javascript 复制代码
import forge from 'node-forge';

let ed25519 = forge.pki.ed25519;

let password = 'Mai9ohgh6ahxee0jutheew0pungoozil';
const seed = forge.util.encodeUtf8(password);
let keypair = ed25519.generateKeyPair({ seed: seed });

let sha256 = forge.md.sha256.create();
sha256.update('hello world!', 'utf8');

let signature = ed25519.sign({
    md: sha256,
    privateKey: keypair.privateKey
});

let verify = ed25519.verify({
    md: sha256,
    publicKey: keypair.publicKey,
    signature: signature
});
if (verify) {
    console.log('🎉 验签通过!消息未被篡改,签名合法有效');
} else {
    console.error('❌ 验签失败!消息已被篡改或签名不合法');
}

4.forge.pki.ed25519对象

函数名 功能描述 参数说明 返回值说明
generateKeyPair 生成公钥/私钥对 options:加密/解密的启动配置项 -seed:种子,支持Buffer|Uint8Array|String 生成ED25519密钥对,可选传入种子生成确定性密钥对
privateKeyFromAsn1 从ASN.1编码对象中解析提取ED25519私钥 obj:必传,ASN.1编码格式的对象,包含私钥信息 返回包含私钥字节数据的对象,privateKeyBytes为Buffer|Uint8Array类型的私钥数据
publicKeyFromAsn1 从ASN.1编码对象中解析提取ED25519公钥 obj:必传,ASN.1编码格式的对象,包含公钥信息 返回Buffer|Uint8Array类型的ED25519公钥
publicKeyFromPrivateKey 从ED25519私钥中推导对应的公钥(ED25519特性:私钥可推导公钥) options:必传配置对象 -options.privateKey:ED25519私钥,支持NativeBuffer、forge ByteBuffer、二进制字符串 返回Buffer|Uint8Array类型的对应公钥(与私钥配对)
sign 对消息进行ED25519签名,生成不可篡改的数字签名 options:必传配置对象 -md:哈希加密对象 -message:普通消息加密 -encoding:编码,支持"binary"|"utf8" -privateKey:签名用私钥,支持BinaryBuffer类型 返回Buffer|Uint8Array类型的ED25519签名(固定64字节)
verify 验证ED25519签名的有效性,确认消息是否被篡改、签名是否合法 options:必传配置对象 -md:哈希加密对象 -message:普通消息加密 -encoding:编码,支持"binary"|"utf8" -signature:待验证的签名,支持BinaryBuffer类型 -publicKey:配对的公钥,支持BinaryBuffer类型 返回布尔值: true表示验签通过(消息未篡改、签名合法); false表示验签失败(消息篡改或签名非法)

七、RSA非对称加密

名称 核心特性 优点 缺点 适用场景
RSA 基于大整数分解难题,支持加密/解密、签名/验签,常用密钥长度2048/4096位 1. 兼容性极强,所有加密库/系统均支持; 2. 功能全面(加密+签名) 1. 运算速度慢(尤其是4096位密钥); 2. 密钥/密文长度长,资源消耗大; 3. 抗量子攻击能力弱 1. 传统系统的加密/签名(如HTTPS证书、文件加密); 2. 需兼容老旧设备的场景
RSA-KEM 基于RSA的密钥封装算法,用于安全传输对称密钥 1. 解决RSA直接加密大数据的效率问题; 2. 安全性依赖RSA的数学难题 1. 仅用于密钥封装,功能单一; 2. 效率仍低于椭圆曲线类KEM 1. 对称密钥的安全分发(如AES密钥通过RSA-KEM传输); 2. 传统加密系统的密钥交换

1.哈希签名

javascript 复制代码
import forge from 'node-forge';

let rsa = forge.pki.rsa;
let keypair = rsa.generateKeyPair({ bits: 2048, e: 65537 });
let sha1 = forge.md.sha1.create();
sha1.update('hello world', 'utf8');
let signature = keypair.privateKey.sign(sha1);

let verify = keypair.publicKey.verify(sha1.digest().bytes(), signature);

if (verify) {
    console.log('🎉 验签通过!消息未被篡改,签名合法有效');
} else {
    console.error('❌ 验签失败!消息已被篡改或签名不合法');
}

2.RSA-PSS签名

javascript 复制代码
import forge from 'node-forge';

let rsa = forge.pki.rsa;
let keypair = rsa.generateKeyPair({ bits: 2048, e: 65537 });

let sha1 = forge.md.sha1.create();
sha1.update('hello world', 'utf8');

let pss = forge.pss.create({
    md: forge.md.sha1.create(),
    mgf: forge.mgf.mgf1.create(forge.md.sha1.create()),
    saltLength: 20
});
let signature = keypair.privateKey.sign(sha1, pss);

let verify = keypair.publicKey.verify(sha1.digest().getBytes(), signature, pss);

if (verify) {
    console.log('🎉 验签通过!消息未被篡改,签名合法有效');
} else {
    console.error('❌ 验签失败!消息已被篡改或签名不合法');
}

3.RSA数据加密

javascript 复制代码
import forge from 'node-forge';

let rsa = forge.pki.rsa;
let keypair = rsa.generateKeyPair({ bits: 2048, e: 65537 });

const plainText = 'hello world';

const encrypted = keypair.publicKey.encrypt(plainText);
console.log('加密后的密文:', forge.util.bytesToHex(encrypted));
const decrypted = keypair.privateKey.decrypt(encrypted);
console.log('解密后的明文:', decrypted);

console.log('');

const encryptedRSAES = keypair.publicKey.encrypt(plainText,'RSAES-PKCS1-V1_5');
console.log('RSAES加密后的密文:', forge.util.bytesToHex(encryptedRSAES));
const decryptedRSAES = keypair.privateKey.decrypt(encryptedRSAES,'RSAES-PKCS1-V1_5');
console.log('RSAES解密后的明文:', decryptedRSAES);

console.log('');

const encryptedRSA = keypair.publicKey.encrypt(plainText,'RSA-OAEP');
console.log('RSA加密后的密文:', forge.util.bytesToHex(encryptedRSA));
const decryptedRSA = keypair.privateKey.decrypt(encryptedRSA,'RSA-OAEP');
console.log('RSA解密后的明文:', decryptedRSA);

console.log('');

let encryptedRSASha256 = keypair.publicKey.encrypt(plainText, 'RSA-OAEP', {
    md: forge.md.sha256.create(),
    mgf1: {
        md: forge.md.sha1.create()
    }
});
let decryptedRSASha256 = keypair.privateKey.decrypt(encryptedRSASha256, 'RSA-OAEP', {
    md: forge.md.sha256.create(),
    mgf1: {
        md: forge.md.sha1.create()
    }
});
console.log('RSA-SHA256加密后的密文:', forge.util.bytesToHex(encryptedRSASha256));
console.log('RSA-SHA256解密后的明文:', decryptedRSASha256);

4.RSA-KEM密钥交换

javascript 复制代码
import forge from 'node-forge';

// 通信方A生成RSA密钥对,公开公钥
let rsa = forge.pki.rsa;
let keypair = rsa.generateKeyPair({ bits: 2048, e: 65537 });

// 通信方B用RSA-KEM封装对称密钥
let kdf1 = new forge.kem.kdf1(forge.md.sha1.create());
let kem = forge.kem.rsa.create(kdf1);
let result = kem.encrypt(keypair.publicKey, 16); // 封装生成对称密钥(长度16对应AES-128)
const aesKey = kem.decrypt(keypair.privateKey, result.encapsulation, 16);// 3B将封装结果(encapsulation)发送给A,A用私钥解密,得到对称密钥

const plainText = 'hello world';
let iv = forge.random.getBytesSync(12);
let cipher = forge.cipher.createCipher('AES-GCM', result.key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer( plainText));
cipher.finish();
let encrypted = cipher.output.getBytes();
let tag = cipher.mode.tag.getBytes();
console.log('\nAES-GCM加密结果:');
console.log('密文:', forge.util.bytesToHex(encrypted));
console.log('IV:', forge.util.bytesToHex(iv));
console.log('认证标签:', forge.util.bytesToHex(tag));

let decipher = forge.cipher.createDecipher('AES-GCM', aesKey);
decipher.start({ iv: iv, tag: tag, tagLength: 128 });
decipher.update(forge.util.createBuffer(encrypted));
decipher.finish();
console.log('\nAES-GCM解密结果:', decipher.output.toString());

5.forge.pki.ed25519对象

函数名 功能描述 参数说明 返回值说明
generateKeyPair 生成RSA密钥对,支持两种参数格式,可选异步回调(适用于大密钥位数生成) options:配置对象 • bits:可选,number类型,RSA密钥位数,常用2048/4096,默认无,推荐2048 • e:可选,number类型,RSA公钥指数,默认65537(0x10001),为工业标准值 • workerScript:可选,string类型,浏览器环境下Web Worker脚本路径,用于异步生成大位数密钥 • workers:可选,number类型,配合workerScript的Web Worker数量,默认1 • workLoad:可选,number类型,每个Web Worker的工作负载分配参数 • prng:可选,any类型,伪随机数生成器,默认用forge内置安全PRNG • algorithm:可选,string类型,密钥生成算法类型,默认"rsa" callback:可选,异步回调函数 返回KeyPair类型的RSA密钥对对象,包含publicKey(公钥)和privateKey(私钥)两个属性

6.公钥对象

属性名 类型 详细说明 参数说明 返回值说明
n number RSA公钥的模数,是一个超大整数,由两个大素数p和q相乘得到,是RSA算法的核心参数之一 - -
e number RSA公钥的指数(公共指数),常用值为65537(0x10001),与私钥指数d对应,用于加密和验签运算 - -
encrypt Function 用于对明文进行RSA加密,遵循"公钥加密"原则,只有对应的私钥才能解密该密文 1. data:必传,Bytes类型,待加密的明文数据(二进制字符串/字节) 2. scheme:可选,加密方案,支持"RSAES-PKCS1-V1_5"、"RSA-OAEP"、"RAW"等 3. schemeOptions:可选,对应加密方案的配置项(如OAEP模式的哈希算法) 加密后的密文数据(二进制格式)
verify Function 用于验证数字签名的有效性,遵循"公钥验签"原则,验证签名是否由对应私钥生成,消息是否完整 1. digest:必传,Bytes类型,原始消息的哈希摘要数据 2. signature:必传,Bytes类型,待验证的数字签名(二进制格式) 3. scheme:可选,签名验证方案,支持"RSASSA-PKCS1-V1_5"、"PSS"等 布尔值(boolean): true表示验签通过,签名合法且消息未被改; false表示验签失败

7.私钥对象

属性名 类型 详细说明 参数说明 返回值说明
n number RSA私钥的模数,与对应公钥的模数n完全一致,由大素数p和q相乘得到 - -
e number RSA私钥中存储的公钥指数,与对应公钥的指数e完全一致,仅用于参数完整性存储 - -
d number RSA私钥的核心指数(私钥指数),是公钥指数e关于(p-1)(q-1)的模逆元,用于解密和签名运算 - -
p number 生成模数n的大素数因子之一,属于私钥核心机密,不可泄露 - -
q number 生成模数n的另一个大素数因子之一,与p成对存在,属于私钥核心机密 - -
dP number 私钥指数d关于(p-1)的模逆元(即d mod (p-1)),用于优化RSA运算速度 - -
dQ number 私钥指数d关于(q-1)的模逆元(即d mod (q-1)),用于优化RSA运算速度 - -
qInv number 素数q关于素数p的模逆元(即q^-1 mod p),用于优化RSA解密和签名效率 - -
decrypt Function 用于对密文进行RSA解密,遵循"私钥解密"原则,仅能解密对应公钥加密的密文 1. data:必传,Bytes,待解密的密文数据(二进制格式) 2. scheme:可选,解密方案,需与加密时的scheme一致 3. schemeOptions:可选,对应解密方案的配置项 解密后的明文数据(二进制格式)
sign Function 生成数字签名(二进制格式),遵循"私钥签名"原则,仅能由对应公钥验证 1. md:必传,哈希对象 2. scheme:可选,签名验证方案,支持"RSASSA-PKCS1-V1_5"、"PSS"等 二进制签名

八、X.509数字证书

X.509 是一种数字证书格式标准,其证书内容包含公钥、身份信息、签发者签名等核心数据,是网络安全领域中广泛使用的证书规范。

优点

  • 是 HTTPS/SSL/TLS 协议的核心证书格式,支撑了主流网络通信的安全加密;
  • 支持证书链信任体系,可通过多级 CA(证书颁发机构)实现跨机构的身份信任传递。

缺点

  • 格式设计复杂,对证书的解析、处理需要额外的技术成本;
  • 证书吊销机制(如 CRL 证书吊销列表、OCSP 在线证书状态协议)存在效率问题,可能影响验证速度。

适用场景

  • 网络通信的身份认证:如网站 HTTPS 证书、代码签名证书等;
  • 企业级 PKI(公钥基础设施)体系:用于企业内部的身份管理、数据加密等安全场景。

1.X.509密钥转换

javascript 复制代码
import forge from 'node-forge';

let pki = forge.pki;

// 生成简易RSA密钥对(2048位,快速生成)
const rsaKeypair = pki.rsa.generateKeyPair({ bits: 2048, e: 65537 });
console.log('1. 原始RSA公钥对象:', rsaKeypair.publicKey);

// 将Forge公钥转为PEM格式
const pemPublicKey = pki.publicKeyToPem(rsaKeypair.publicKey);
console.log('2. RSA公钥转换为PEM格式:', pemPublicKey);

// 将PEM格式公钥解析为Forge公钥
let publicKey = pki.publicKeyFromPem(pemPublicKey);
console.log('3. PEM格式公钥解析为RSA公钥对象:', publicKey);

// 将Forge公钥转为ASN.1 SubjectPublicKeyInfo
let subjectPublicKeyInfo = pki.publicKeyToAsn1(publicKey);
console.log('4. RSA公钥转换为ASN.1 SubjectPublicKeyInfo格式:', subjectPublicKeyInfo);

// 将ASN.1 SubjectPublicKeyInfo解析为Forge公钥
publicKey = pki.publicKeyFromAsn1(subjectPublicKeyInfo);
console.log('5. ASN.1格式解析为RSA公钥对象:', publicKey);

// 获取SHA-1算法的RSAPublicKey格式指纹(字节缓冲)
const fingerprint = pki.getPublicKeyFingerprint(publicKey);
console.log('6. SHA-1 RSAPublicKey格式公钥指纹(字节缓冲):', fingerprint);

// 获取SHA-1算法的SubjectPublicKeyInfo格式指纹(字节缓冲)
const spkiFingerprint = pki.getPublicKeyFingerprint(publicKey, { type: 'SubjectPublicKeyInfo' });
console.log('7. SHA-1 SubjectPublicKeyInfo格式公钥指纹(字节缓冲):', spkiFingerprint);

// 获取16进制、冒号分隔的SHA-1 RSAPublicKey格式公钥指纹
const spkiFingerprintHex = pki.getPublicKeyFingerprint(publicKey, { encoding: 'hex', delimiter: ':' });
console.log('8. 16进制冒号分隔的SHA-1 RSAPublicKey格式公钥指纹:', spkiFingerprintHex);

// 获取16进制、冒号分隔的SHA-1 SubjectPublicKeyInfo格式公钥指纹
const spkiFingerprintHexColon = pki.getPublicKeyFingerprint(publicKey, {
    type: 'SubjectPublicKeyInfo',
    encoding: 'hex',
    delimiter: ':'
});
console.log('9. 16进制冒号分隔的SHA-1 SubjectPublicKeyInfo格式公钥指纹:', spkiFingerprintHexColon);

// 获取16进制、冒号分隔的MD5 RSAPublicKey格式公钥指纹
const rsaFingerprintHexColon = pki.getPublicKeyFingerprint(publicKey, {
    md: forge.md.md5.create(),
    encoding: 'hex',
    delimiter: ':'
});
console.log('10. 16进制冒号分隔的MD5 RSAPublicKey格式公钥指纹:', rsaFingerprintHexColon);

2.创建X.509 v3证书

javascript 复制代码
import forge from 'node-forge';

let pki = forge.pki;
const now = new Date();


let keys = pki.rsa.generateKeyPair(2048);
let cert = pki.createCertificate();

// 手动为证书绑定公钥(核心:确保证书包含对应的公钥信息,用于后续加密、验签等操作)
cert.publicKey = keys.publicKey;
// 设置证书版本为X.509 v3(目前广泛使用的证书版本,支持扩展字段,v1/v2已基本淘汰)
cert.version = 3;
// 生成随机唯一的证书序列号(16字节随机数转换为十六进制字符串,用于唯一标识证书,避免重复)
cert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16));
// 设置证书生效起始时间为当前时间(证书在此时间之后才具有法律效力/可用性)
cert.validity.notBefore = now;
// 先将证书过期时间初始化为当前时间(后续再进行年份偏移调整,作为有效期设置的过渡步骤)
cert.validity.notAfter = new Date(now.getTime());
// 调整证书过期时间:在生效起始时间基础上增加10年,最终设置证书有效期为10年(长期信任根CA常用有效期)
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10);

// 证书主体/签发者属性数组(X.509证书的身份标识字段,用于描述证书所属主体/签发CA的信息)
const caAttrs = [
    // commonName(CN):通用名称,根CA证书通常填写CA名称,终端证书可填写域名/用户名等
    { name: 'commonName', value: 'My Trusted Root CA' },
    // countryName(C):国家代码,使用ISO 3166-1 alpha-2格式,CN代表中国
    { name: 'countryName', value: 'CN' },
    // stateOrProvinceName(ST):州/省份名称,填写完整的行政区划名称(与下方shortName: 'ST'是同一字段的不同写法)
    { name: 'stateOrProvinceName', value: 'Beijing' },
    // localityName(L):地区/城市名称,填写具体的城市或区县名称
    { name: 'localityName', value: 'Beijing' },
    // organizationName(O):组织/机构名称,填写所属单位或企业的正式名称
    { name: 'organizationName', value: 'My CA Organization' },
    // shortName: 'ST':州/省份的简写标识,与上方stateOrProvinceName对应,值为Virginia(美国弗吉尼亚州,演示不同地区写法)
    { shortName: 'ST', value: 'Virginia' },
    // shortName: 'OU':organizationalUnitName(组织单元)的简写,填写机构内部的部门或团队名称
    { shortName: 'OU', value: 'Test' }
];
cert.setIssuer(caAttrs); // 设置证书的签发者信息(自签名CA证书中,签发者与主体信息一致)
cert.setSubject(caAttrs); // 设置证书的主体信息(描述证书的拥有者,此处为根CA自身)

//添加CA证书必备扩展字段
cert.setExtensions([
    // 基础约束扩展:标记该证书为CA证书(cA: true),该扩展为关键扩展(critical: true),缺少或不合法会导致证书验证失败
    { name: 'basicConstraints', cA: true, critical: true },
    // 密钥用法扩展:限定密钥用途为证书签名(keyCertSign: true)和CRL签名(cRLSign: true),为关键扩展,确保CA证书仅用于签发证书和吊销列表
    { name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true },
    // 主题密钥标识扩展:通过公钥计算唯一标识,用于关联证书与对应的密钥,方便证书链构建和密钥匹配,自动关联证书中的公钥
    { name: 'subjectKeyIdentifier' },
    // 权威密钥标识扩展:自签名证书中,权威密钥标识与主题密钥标识一致(keyIdentifier: true),用于标识签发该证书的CA公钥,方便验证证书链的连续性
    { name: 'authorityKeyIdentifier', keyIdentifier: true },
    // 扩展密钥用法扩展:限定证书的额外应用场景,支持服务器身份认证(serverAuth)、客户端身份认证(clientAuth)、代码签名(codeSigning)、邮件保护(emailProtection)、时间戳服务(timeStamping)
    { name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true, timeStamping: true },
    // Netscape证书类型扩展:兼容旧版Netscape浏览器,标记证书可用于客户端认证(client)、服务器认证(server)、邮件加密(email)、对象签名(objsign)、SSL CA(sslCA)、邮件CA(emailCA)、对象CA(objCA)
    { name: 'nsCertType', client: true, server: true, email: true, objsign: true, sslCA: true, emailCA: true, objCA: true },
    // 主题备用名称扩展:补充证书主体的额外标识,包含URI类型(type: 6,对应http://example.org/webid#me)和IP地址类型(type: 7,对应127.0.0.1),解决主体通用名称的局限性
    { name: 'subjectAltName', altNames: [{ type: 6, value: 'http://example.org/webid#me' }, { type: 7, ip: '127.0.0.1' }] }
]);

//自签名证书(核心:签名过程中会自动将公钥嵌入证书)
cert.sign(keys.privateKey, forge.md.sha256.create());

const endEntityCertPem = pki.certificateToPem(cert);
console.log('✅ 证书生成完成(PEM格式):\n', endEntityCertPem);

const certCommonName = cert.subject.getField({ name: 'commonName' })?.value;
// 组织名称(O)
const certOrg = cert.subject.getField({ name: 'organizationName' })?.value;
// 国家代码(C)
const certCountry = cert.subject.getField({ name: 'countryName' })?.value;
console.log(`证书通用名称(CN):${certCommonName}`);
console.log(`所属组织(O):${certOrg}`);
console.log(`国家代码(C):${certCountry}`);
console.log(`证书版本:X.509 v${cert.version}`);
console.log(`证书序列号:${cert.serialNumber}`);

3.X.509 数字证书验证(中间 CA 不是必须项)

javascript 复制代码
import forge from 'node-forge';

let pki = forge.pki;
const now = new Date();

// ===================== 步骤1:生成根CA证书 =====================
let rootCaKeypair = pki.rsa.generateKeyPair(2048);
let rootCaCert = pki.createCertificate();
// 手动为证书绑定公钥(核心:确保证书包含对应的公钥信息,用于后续加密、验签等操作)
rootCaCert.publicKey = rootCaKeypair.publicKey;
// 设置证书版本为X.509 v3(目前广泛使用的证书版本,支持扩展字段,v1/v2已基本淘汰)
rootCaCert.version = 3;
// 生成随机唯一的证书序列号(16字节随机数转换为十六进制字符串,用于唯一标识证书,避免重复)
rootCaCert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16));
// 设置证书生效起始时间为当前时间(证书在此时间之后才具有法律效力/可用性)
rootCaCert.validity.notBefore = now;
// 先将证书过期时间初始化为当前时间(后续再进行年份偏移调整,作为有效期设置的过渡步骤)
rootCaCert.validity.notAfter = new Date(now.getTime());
// 调整证书过期时间:在生效起始时间基础上增加10年,最终设置证书有效期为10年(长期信任根CA常用有效期)
rootCaCert.validity.notAfter.setFullYear(rootCaCert.validity.notBefore.getFullYear() + 10);

// 证书主体/签发者属性数组(X.509证书的身份标识字段,用于描述证书所属主体/签发CA的信息)
const rootCaAttrs = [
    // commonName(CN):通用名称,根CA证书通常填写CA名称,终端证书可填写域名/用户名等
    { name: 'commonName', value: 'My Trusted Root CA' },
    // countryName(C):国家代码,使用ISO 3166-1 alpha-2格式,CN代表中国
    { name: 'countryName', value: 'CN' },
    // stateOrProvinceName(ST):州/省份名称,填写完整的行政区划名称(与下方shortName: 'ST'是同一字段的不同写法)
    { name: 'stateOrProvinceName', value: 'Beijing' },
    // localityName(L):地区/城市名称,填写具体的城市或区县名称
    { name: 'localityName', value: 'Beijing' },
    // organizationName(O):组织/机构名称,填写所属单位或企业的正式名称
    { name: 'organizationName', value: 'My CA Organization' },
    // shortName: 'ST':州/省份的简写标识,与上方stateOrProvinceName对应,值为Virginia(美国弗吉尼亚州,演示不同地区写法)
    { shortName: 'ST', value: 'Virginia' },
    // shortName: 'OU':organizationalUnitName(组织单元)的简写,填写机构内部的部门或团队名称
    { shortName: 'OU', value: 'Test' }
];
rootCaCert.setIssuer(rootCaAttrs); // 设置证书的签发者信息(自签名CA证书中,签发者与主体信息一致)
rootCaCert.setSubject(rootCaAttrs); // 设置证书的主体信息(描述证书的拥有者,此处为根CA自身)

//添加CA证书必备扩展字段
rootCaCert.setExtensions([
    // 基础约束扩展:标记该证书为CA证书(cA: true),该扩展为关键扩展(critical: true),缺少或不合法会导致证书验证失败
    { name: 'basicConstraints', cA: true, critical: true },
    // 密钥用法扩展:限定密钥用途为证书签名(keyCertSign: true)和CRL签名(cRLSign: true),为关键扩展,确保CA证书仅用于签发证书和吊销列表
    { name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true },
    // 主题密钥标识扩展:通过公钥计算唯一标识,用于关联证书与对应的密钥,方便证书链构建和密钥匹配,自动关联证书中的公钥
    { name: 'subjectKeyIdentifier' },
    // 权威密钥标识扩展:自签名证书中,权威密钥标识与主题密钥标识一致(keyIdentifier: true),用于标识签发该证书的CA公钥,方便验证证书链的连续性
    { name: 'authorityKeyIdentifier', keyIdentifier: true },
    // 扩展密钥用法扩展:限定证书的额外应用场景,支持服务器身份认证(serverAuth)、客户端身份认证(clientAuth)、代码签名(codeSigning)、邮件保护(emailProtection)、时间戳服务(timeStamping)
    { name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true, timeStamping: true },
    // Netscape证书类型扩展:兼容旧版Netscape浏览器,标记证书可用于客户端认证(client)、服务器认证(server)、邮件加密(email)、对象签名(objsign)、SSL CA(sslCA)、邮件CA(emailCA)、对象CA(objCA)
    { name: 'nsCertType', client: true, server: true, email: true, objsign: true, sslCA: true, emailCA: true, objCA: true },
    // 主题备用名称扩展:补充证书主体的额外标识,包含URI类型(type: 6,对应http://example.org/webid#me)和IP地址类型(type: 7,对应127.0.0.1),解决主体通用名称的局限性
    { name: 'subjectAltName', altNames: [{ type: 6, value: 'http://example.org/webid#me' }, { type: 7, ip: '127.0.0.1' }] }
]);

//自签名证书(核心:签名过程中会自动将公钥嵌入证书)
rootCaCert.sign(rootCaKeypair.privateKey, forge.md.sha256.create());
const rootCaCertPem = pki.certificateToPem(rootCaCert);
console.log('✅ 根CA证书生成完成(PEM格式):\n', rootCaCertPem.slice(0, 100) + '...\n');

// ===================== 步骤2:生成中间CA密钥对与证书(由根CA签发) =====================
const intermediateCaKeypair = pki.rsa.generateKeyPair(2048);
const intermediateCaCert = pki.createCertificate();
intermediateCaCert.publicKey = intermediateCaKeypair.publicKey;
intermediateCaCert.version = 3;
intermediateCaCert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16));
intermediateCaCert.validity.notBefore = now;
intermediateCaCert.validity.notAfter = new Date(now.getTime());
intermediateCaCert.validity.notAfter.setFullYear(intermediateCaCert.validity.notBefore.getFullYear() + 10);
// 中间CA身份信息
const intermediateCaAttrs = [
    { name: 'commonName', value: 'My Intermediate CA' },
    { name: 'countryName', value: 'CN' },
    { name: 'organizationName', value: 'My Root CA Org' },
    { shortName: 'OU', value: 'Intermediate CA Department' }
];
intermediateCaCert.setSubject(intermediateCaAttrs);
intermediateCaCert.setIssuer(rootCaAttrs); // 由根CA签发
// 中间CA扩展字段
intermediateCaCert.setExtensions([
    { name: 'basicConstraints', cA: true, pathLenConstraint: 0, critical: true }, // 允许签发终端证书,不可再签下级CA
    { name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true },
    { name: 'subjectKeyIdentifier' },
    { name: 'authorityKeyIdentifier', keyIdentifier: true }
]);
// 根CA签发中间CA证书
intermediateCaCert.sign(rootCaKeypair.privateKey, forge.md.sha256.create());
const intermediateCaCertPem = pki.certificateToPem(intermediateCaCert);
console.log('✅ 中间CA证书生成完成(PEM格式):\n', intermediateCaCertPem.slice(0, 100) + '...\n');

// ===================== 步骤3:生成终端证书(由中间CA签发,用于服务器/客户端认证) =====================
const endEntityKeypair = pki.rsa.generateKeyPair(2048);
const endEntityCert = pki.createCertificate();
endEntityCert.publicKey = endEntityKeypair.publicKey;
endEntityCert.version = 3;
endEntityCert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16));
endEntityCert.validity.notBefore = now;
endEntityCert.validity.notAfter = new Date(now.getTime());
endEntityCert.validity.notAfter.setFullYear(endEntityCert.validity.notBefore.getFullYear() + 10);

// 终端证书身份信息(服务器域名)
const endEntityAttrs = [
    { name: 'commonName', value: 'www.example.com' },
    { name: 'countryName', value: 'CN' },
    { name: 'organizationName', value: 'Example Company' },
    { shortName: 'OU', value: 'IT Department' }
];
endEntityCert.setSubject(endEntityAttrs);
endEntityCert.setIssuer(intermediateCaAttrs); // 由中间CA签发
// 终端证书扩展字段
endEntityCert.setExtensions([
    { name: 'basicConstraints', cA: false, critical: true }, // 非CA证书,不可签发其他证书
    { name: 'keyUsage', digitalSignature: true, keyEncipherment: true, critical: true }, // 用于数字签名和密钥加密
    { name: 'subjectKeyIdentifier' },
    { name: 'authorityKeyIdentifier', keyIdentifier: true },
    { name: 'extKeyUsage', serverAuth: true, clientAuth: true }, // 支持服务器和客户端认证
    { name: 'subjectAltName', altNames: [ // 备用域名/IP,解决CN局限性
        { type: 2, value: 'www.example.com' },
        { type: 2, value: 'api.example.com' },
        { type: 7, ip: '192.168.1.100' }
    ] }
]);
// 中间CA签发终端证书
endEntityCert.sign(intermediateCaKeypair.privateKey, forge.md.sha256.create());
const endEntityCertPem = pki.certificateToPem(endEntityCert);
console.log('✅ 终端证书生成完成(PEM格式):\n', endEntityCertPem.slice(0, 100) + '...\n');

// ===================== 步骤4:创建CA信任仓库并管理证书  =====================
const caStore = pki.createCaStore([rootCaCertPem]);
console.log('✅ CA信任仓库初始化完成,已导入根CA证书');

// 向仓库添加中间CA证书(支持PEM字符串或证书对象)
caStore.addCertificate(intermediateCaCert); // 也可传入intermediateCaCert(证书对象)
console.log('✅ 中间CA证书已添加到CA信任仓库');

// const issuerCert = caStore.getIssuer(endEntityCert);
// console.log(issuerCert.subject);
// const issuerCommonName = issuerCert.subject.getField({ name: 'commonName' });
// console.log(issuerCommonName);

// ===================== 步骤5:验证证书链有效性 =====================
const certChain = [endEntityCert, intermediateCaCert, rootCaCert];
const verifyResult = pki.verifyCertificateChain(
    caStore,
    certChain,
    (verified, depth, certs) =>
    {
        if (!verified) {
            console.error(`❌ 深度${depth}的证书基础验证失败(签名/格式不合法)`);
            return false;
        }


        const cert = certs[depth];

        const certCommonName = cert.subject.getField({ name: 'commonName' })?.value;
        // 组织名称(O)
        const certOrg = cert.subject.getField({ name: 'organizationName' })?.value;
        // 国家代码(C)
        const certCountry = cert.subject.getField({ name: 'countryName' })?.value;

        // 4. 打印当前验证进度信息
        console.log(`\n==================== 证书验证(深度${depth}) ====================`);
        console.log(`证书通用名称(CN):${certCommonName}`);
        console.log(`所属组织(O):${certOrg}`);
        console.log(`国家代码(C):${certCountry}`);
        console.log(`证书版本:X.509 v${cert.version}`);
        console.log(`证书序列号:${cert.serialNumber}`);

        const currentTime = new Date();
        const notBefore = cert.validity?.notBefore;
        const notAfter = cert.validity?.notAfter;

        console.log(`生效时间:${notBefore.toLocaleString()}`);
        console.log(`过期时间:${notAfter.toLocaleString()}`);

        if (currentTime < notBefore) {
            console.error(`❌ 证书${certCommonName}尚未生效(当前时间早于生效时间)`);
            return false;
        }
        if (currentTime > notAfter) {
            console.error(`❌ 证书${certCommonName}已过期(当前时间晚于过期时间)`);
            return false;
        }

        // 6校验终端证书(depth=0)的备用名称是否包含目标域名
        if (depth === 0) {
            const sanExtension = cert.getExtension('subjectAltName');
            if (!sanExtension) {
                console.warn(`⚠️  终端证书${certCommonName}缺少主题备用名称(SAN)扩展`);
                // 若需强制校验SAN,可改为return false
                // return false;
            } else {
                const targetDomain = 'www.example.com';
                const hasTargetDomain = sanExtension.altNames.some((altName) =>
                    altName.type === 2 && altName.value === targetDomain
                );

                if (hasTargetDomain) {
                    console.log(`✅ 终端证书包含目标域名:${targetDomain}`);
                } else {
                    console.error(`❌ 终端证书不包含目标域名:${targetDomain}`);
                    console.log('证书包含的备用名称:', sanExtension.altNames.map((alt) => `${alt.type === 2 ? '域名' : 'IP'}: ${alt.value || alt.ip}`).join(', '));
                    return false;
                }
            }
        }

        //  校验CA证书(depth>0)是否具备证书签发权限
        if (depth > 0) {
            const basicConstraints = cert.getExtension('basicConstraints');
            if (!basicConstraints?.cA) {
                console.error(`❌ 深度${depth}的证书${certCommonName}不是CA证书,不具备签发权限`);
                return false;
            }
            console.log(`✅ CA证书${certCommonName}具备证书签发权限`);
        }

        return true; // 返回true表示该证书验证通过
    }
);

if (verifyResult) {
    console.log('\n🎉 证书链验证成功!终端证书可信且有效');
}

4.cert = pki.createCertificate()对象函数,创建证书

函数名 描述 参数说明 返回值说明
setSubject 设置证书的主体(拥有者)信息,可选指定唯一ID 1. attrs: CertificateField[] - 主体属性数组 2. uniqueId?: string - 可选唯一ID void - 无返回值
setIssuer 设置证书的签发者信息,可选指定唯一ID 1. attrs: CertificateField[] - 签发者属性数组 2. uniqueId?: string - 可选唯一ID void - 无返回值
setExtensions 为证书设置扩展字段数组,配置X.509 v3证书的扩展信息 1. exts: any[] - 证书扩展字段数组 void - 无返回值
getExtension 根据扩展名称或ID获取证书指定扩展字段,未找到返回undefined 1. options: string | {name: string} | {id: number} - 扩展名称或ID配置 {} | undefined - 扩展对象或undefined
sign 使用指定私钥对证书进行签名,可选指定消息摘要算法 1. key: pki.rsa.PrivateKey - 签名用私钥 2. md?: md.MessageDigest - 可选消息摘要对象(默认SHA1) void - 无返回值
verify 使用当前证书的公钥,验证传入的子证书签名是否有效 1. child: Certificate - 待验证的子证书对象 boolean - true = 验证通过, false = 验证失败
isIssuer 检查当前证书的签发者是否与传入父证书的主体匹配(不验证签名) 1. parent: Certificate - 待检验的父证书对象 boolean - true = 匹配, false = 不匹配
issued 检查当前证书的主体是否与传入子证书的签发者匹配(不验证签名) 1. child: Certificate - 待校验的子证书对象 boolean - true = 匹配, false = 不匹配
generateSubjectKeyIdentifier 生成当前证书的主体密钥标识符(SKI),返回字节缓冲区格式 无参数 util.ByteStringBuffer - 字节缓冲区格式的SKI
verifySubjectKeyIdentifier 验证证书的主体密钥标识符扩展值与公钥是否一致,无该扩展返回false 无参数 boolean - true = 验证通过, false = 验证失败

5.cert = pki.createCertificate()对象属性,创建证书

属性名称 类型定义 说明描述
version number 证书版本号,通常为3(对应X.509 v3标准,主流证书版本)
serialNumber string 证书唯一序列号,用于唯一标识单个证书,防止重复签发
signatureOid string 签名算法的对象标识符(OID),用于标识证书签名所采用的算法类型
signature any 证书的数字签名内容,用于验证证书的完整性和签发者身份的真实性
signInfo { algorithmOid: string; parameters: any; } 签名详细信息,包含签名算法OID和对应的算法配置参数
validity { notBefore: Date; notAfter: Date; } 证书有效期范围,notBefore为生效时间,notAfter为过期时间
issuer { getField: (sn: string | CertificateFieldOptions) => any; addField: (attr: CertificateField) => void; attributes: CertificateField[]; hash: any; } 证书签发者信息,包含字段操作方法、签发者属性数组和对应的哈希值
subject { getField: (sn: string | CertificateFieldOptions) => any; addField: (attr: CertificateField) => void; attributes: CertificateField[]; hash: any; } 证书主体(拥有者)信息,包含字段操作方法、主体属性数组和对应的哈希值
extensions any[] 证书扩展字段数组,存储X.509 v3证书的扩展信息(如SAN、BasicConstraints等)
privateKey PrivateKey 与证书对应的私钥,用于证书签名、数据解密等私密操作
publicKey PublicKey 与证书对应的公钥,对外公开,用于验证签名、数据加密等公开操作
md md.MessageDigest 消息摘要对象,用于证书签名和验证过程中的哈希计算(默认SHA1)
signatureParameters any 签名算法的附加配置参数,配合签名算法完成完整的签名流程
tbsCertificate asn1.Asn1 待签名证书(To Be Signed Certificate)的ASN.1结构,包含证书核心信息

6.caStore = pki.createCaStore([rootCaCertPem]) 创建一个 CA 信任仓库

函数名 说明 参数说明 返回值类型
addCertificate 向CA证书仓库中添加证书,支持证书对象或PEM格式字符串两种形式 pki.Certificate 无返回值
hasCertificate 检查CA证书仓库中是否存在指定证书,用于验证证书是否已入库 pki.Certificate 返回true或者false
removeCertificate 从CA证书仓库中移除指定证书,返回被移除的证书(若不存在则返回null) pki.Certificate pki.Certificate 证书对象
listAllCertificates 列出CA证书仓库中所有已存储的证书,返回证书对象数组 无参数 pki.Certificate[](所有证书对象组成的数组)
getIssuer 根据目标证书的签发者(subject),从仓库中查找对应的签发CA证书 pki.Certificate pki.Certificate 证书对象
getBySubject 根据证书主题(subject)字符串,从仓库中查找匹配的证书 subject: string:证书主题字符串(如证书的DN字段) pki.Certificate 证书对象

7.其他函数

函数名 描述 参数说明 返回值类型
certificateFromAsn1 将ASN.1结构对象转换为Certificate证书对象,可选是否计算哈希值 1. obj: asn1.Asn1 - 待转换的ASN.1结构对象 2. computeHash?: boolean - 可选,是否计算证书哈希值 Certificate - 转换后的证书对象
certificationRequestFromAsn1 将ASN.1结构对象转换为证书签名请求(CSR)对象,可选是否计算哈希值 1. obj: asn1.Asn1 - 待转换的ASN.1结构对象 2. computeHash?: boolean - 可选,是否计算CSR哈希值 CertificateSigningRequest - 转换后的CSR对象
distinguishedNameToAsn1 将可分辨名称(DN,通常为证书主体/签发者信息)转换为ASN.1结构对象 1. dn: 包含证书属性的可分辨名称对象 • dn.attributes: ReadonlyArray asn1.Asn1 - 转换后的ASN.1结构对象
certificateToAsn1 将Certificate证书对象转换为对应的ASN.1结构对象 1. cert: Certificate - 待转换的证书对象 asn1.Asn1 - 转换后的ASN.1结构对象
certificationRequestToAsn1 将证书签名请求(CSR)对象转换为对应的ASN.1结构对象 1. cert: CertificateSigningRequest - 待转换的CSR对象 asn1.Asn1 - 转换后的ASN.1结构对象
decryptRsaPrivateKey 从PEM格式数据中解密并提取RSA私钥,支持带密码保护的PEM私钥 1. pem: PEM - 包含RSA私钥的PEM格式字符串 2. passphrase?: string - 可选,解密私钥的密码 rsa.PrivateKey - 解密后的RSA私钥对象
createCertificate 创建一个空的、未初始化的Certificate证书对象,用于后续配置证书信息 无参数 Certificate - 空证书对象
certificationRequestToPem 将证书签名请求(CSR)对象转换为PEM格式字符串,可选指定每行最大长度 1. csr: CertificateSigningRequest - 待转换的CSR对象 2. maxline?: number - 可选,PEM字符串每行最大字符数 PEM - 转换后的PEM格式字符串
certificationRequestFromPem 从PEM格式字符串中解析出证书签名请求(CSR)对象,支持严格格式校验 1. pem: PEM - 包含CSR的PEM格式字符串 2. computeHash?: boolean - 可选,是否计算CSR哈希值 3. strict?: boolean - 可选,是否启用严格模式校验 CertificateSigningRequest - 解析后的CSR对象
createCertificationRequest 创建一个空的、未初始化的CertificateSigningRequest(CSR)对象,用于后续配置签名请求信息 无参数 CertificateSigningRequest - 空CSR对象
certificateToPem 将Certificate证书对象转换为PEM格式字符串,可选指定每行最大长度 1. cert: Certificate - 待转换的证书对象 2. maxline?: number - 可选,PEM字符串每行最大字符数 PEM - 转换后的PEM格式字符串
certificateFromPem 从PEM格式字符串中解析出Certificate证书对象,支持严格模式校验 1. pem: PEM - 包含证书的PEM格式字符串 2. computeHash?: boolean - 可选,是否计算证书哈希值 3. strict?: boolean - 可选,是否启用严格模式校验 Certificate - 解析后的证书对象
verifyCertificateChain 验证证书链的有效性,基于指定的CA信任仓库,支持自定义验证回调和有效期校验日期 1. caStore: CAStore - 可信CA信任仓库 2. chain: Certificate[] - 待验证的证书链数组(终端证书→中间CA→根CA) 3. options配置项,可以直接传入函数,或者按照下面属性配置,函数参数与options.verify一致 • options.verify: ((verified: boolean | string, depth: number, certs: Certificate[]) => boolean); • options.validityCheckDate?: Date | null | undefined; boolean - true=证书链验证通过, false=证书链验证失败

8.CertificateSigningRequest 对象

属性/函数名 类型 说明 参数说明 返回值说明
version number 证书签名请求(CSR)的版本号,遵循X.509标准,通常固定为0(对应版本1),保障CSR格式解析兼容性 --- ---
signatureOid string CSR签名所使用算法的OID(对象标识符),如forge.pki.oids.sha256WithRSAEncryption,标识签名算法类型,签名后自动赋值 --- ---
signature any CSR的数字签名结果数据,存储用私钥加密后的摘要信息,验证CSR有效性时需使用对应公钥解密验证 --- ---
signInfo { algorithmOid: string | null } CSR签名算法元数据对象,仅包含algorithmOid字段,记录签名算法的OID,与signatureOid功能一致,用于兼容不同解析逻辑 --- ---
subject Object(嵌套结构) CSR主题(证书申请者)的身份信息对象,存储申请者的国家、组织、通用名称等身份字段,是CSR的核心身份信息载体 --- ---
subject.attributes CertificateField[] 主题身份信息的字段数组,存储所有已添加的申请者身份字段,如{name: 'commonName', value: 'Example Corp'} --- ---
subject.hash any 主题身份信息的哈希值,用于快速校验主题信息是否被篡改,通常由框架自动计算生成 --- ---
publicKey PublicKey 申请者的公钥对象,与申请者的私钥配对,后续用于生成证书的公钥部分,签名CSR前需设置有效公钥 --- ---
attributes CertificateField[] CSR的扩展属性数组,存储除主题身份外的额外信息(如申请联系方式、密钥用法等),可选配置,用于丰富CSR信息 --- ---
md md.MessageDigest 用于生成CSR签名的消息摘要对象,如forge.md.sha256,指定签名时的哈希算法,签名后自动赋值 --- ---
signatureParameters any CSR签名的附加参数对象,存储签名算法的额外配置(如RSA填充模式),多数场景下由框架自动填充,无需手动配置 --- ---
certificationRequestInfo asn1.Asn1 CSR的核心信息ASN.1结构化对象,存储版本、主题、公钥等核心数据,是CSR编码为PEM/DER格式的基础 --- ---
subject.getField Function 从主题身份信息中获取指定字段,通过字段短名或配置项匹配对应身份属性 sn: string(字段短名,如CN对应通用名称)/ CertificateFieldOptions(字段配置项) 匹配到的身份字段值,无匹配则返回空
subject.addField Function 向主题身份信息中添加新的身份字段,完善申请者的身份信息 attr: CertificateField(身份字段对象,包含name、value等属性) void(无返回值)
getAttribute Function 从CSR的扩展属性中获取指定属性,通过属性短名或配置项匹配对应扩展信息 sn: string(属性短名)/ GetAttributeOpts(属性配置项,包含shortName/name/type) Attribute对象 • name:属性含义名称(如commonName) • shortName:可选,属性短名(如CN) • type:属性标准化OID标识 • value:属性实际数据值 • valueTagClass:属性值的ASN.1数据类型标记 • extensions:可选,属性附加扩展信息
addAttribute Function 向CSR的扩展属性中添加新的扩展字段,补充CSR的额外信息 attr: CertificateField(扩展字段对象,包含name、value等属性) void(无返回值)
setSubject Function 批量设置CSR的主题身份信息,覆盖原有主题字段,快速配置申请者身份 attrs: CertificateField[](身份字段数组,包含多个申请者身份属性) void(无返回值)
setAttributes Function 批量设置CSR的扩展属性,覆盖原有扩展字段,快速配置额外信息 attrs: CertificateField[](扩展字段数组,包含多个额外属性) void(无返回值)
sign Function 使用申请者的私钥对CSR进行数字签名,生成有效的CSR数据,签名后CSR方可提交给CA机构申请证书 1. key: pki.rsa.PrivateKey(申请者的RSA私钥,用于签名) 2. md?: md.MessageDigest(可选,消息摘要对象,默认使用SHA1,推荐指定SHA256等强哈希算法) void(无返回值)
verify Function 验证CSR的签名有效性,使用CSR自身的公钥解密签名并对比摘要,判断CSR是否被篡改、签名是否合法 --- boolean(验证通过返回true,失败返回false)

九、公钥基础设施 - PKCS#5 (对称密钥的派生与存储)

PKCS#5 是公钥基础设施下的规范之一,核心用于对称密钥的派生与存储,常用 PBKDF2 算法基于密码生成加密密钥。

优点

  • 增强密码安全性:通过加盐、迭代等方式,提升密码的抗破解能力;
  • 兼容性强:广泛支持各类密码派生场景,是行业常用的密钥生成规范。

缺点

  • 功能单一:仅聚焦密钥派生与存储,无其他扩展安全能力;
  • 早期版本安全性弱:如 PBKDF1 算法的安全强度已无法满足现代需求。

适用场景

  • 用户密码的安全存储:例如数据库中密码的哈希加密存储;
  • 基于密码的加密密钥生成:通过用户密码生成用于数据加密的对称密钥。
javascript 复制代码
import forge from 'node-forge';


// 核心参数配置
const password = 'mySecurePassword123'; // 原始密码
const salt = forge.util.bytesToHex(forge.random.getBytesSync(16)); // 随机盐值(16字节,转十六进制)
const iterations = 10000; // 迭代次数(越高越安全,性能消耗越大)
const keySize = 32; // 生成32字节(256位)密钥,适配AES-256加密

/* forge.pkcs5.pbkdf2 参数
1.password: string - 原始密码字符串(用于推导密钥的基础数据)
2.salt: string - 盐值字符串(防止彩虹表攻击,增加密钥唯一性)
3.iterations: number - 迭代次数(次数越多,破解难度越大,安全性越高)
4.keySize: number - 期望生成的密钥长度(以字节为单位)
5.messageDigest?: md.MessageDigest | md.Algorithm - 可选自定义消息摘要算法(默认使用 SHA1)
6.callback?: (err: Error | null, dk: string) => any - 可选异步回调函数:
-err: 错误对象(推导失败时非空)
-dk: 推导后的密钥字符串(成功时返回有效密钥)
* */
const derivedKey = forge.pkcs5.pbkdf2(password, salt, iterations, keySize);

console.log('原始密码:', password);
console.log('盐值(十六进制):', salt);
console.log('迭代次数:', iterations);
console.log('密钥长度(字节):', keySize);
console.log('推导后的密钥(十六进制):', forge.util.bytesToHex(derivedKey));

十、公钥基础设施 - PKCS#7 (对称密钥的派生与存储)

PKCS#7 是公钥基础设施的规范之一,核心用于加密消息、数字签名、证书封装,支持多接收方、多签名的复杂安全场景。

优点

  • 适配复杂消息安全需求:可同时实现加密、签名、证书携带等复合操作;
  • 是 S/MIME 邮件加密的技术基础,广泛支撑邮件安全场景。

缺点

  • 格式设计冗余,对数据的解析、处理复杂度较高;
  • 兼容性依赖具体实现,不同系统间的互通可能存在差异。

适用场景

  • 安全邮件(S/MIME):实现邮件的加密与签名;
  • 带签名 / 加密的电子文档传输:保障文档在传输过程中的安全性与不可否认性。

1.签名验证

javascript 复制代码
import forge from 'node-forge';


const pkcs7 = forge.pkcs7;
const pki = forge.pki;

const signerKeyPair = pki.rsa.generateKeyPair(2048);

//证书相关文档,教程 "八、X.509数字证书"
const signerCert = pki.createCertificate();
signerCert.publicKey = signerKeyPair.publicKey;
signerCert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16));
signerCert.validity.notBefore = new Date();
signerCert.validity.notAfter = new Date();
signerCert.validity.notAfter.setFullYear(signerCert.validity.notBefore.getFullYear() + 1);
// 设置证书主体/签发者(自签名)
const attrs = [{ name: 'commonName', value: 'Signer CA' }];
signerCert.setSubject(attrs);
signerCert.setIssuer(attrs);
signerCert.sign(signerKeyPair.privateKey, forge.md.sha256.create());

const certOrCertPem = pki.certificateToPem(signerCert);

const signedData = pkcs7.createSignedData();
signedData.content = forge.util.createBuffer('需要签名的敏感数据:用户订单号 #123456', 'utf8');
signedData.addCertificate(certOrCertPem);

signedData.addSigner({
    key: signerKeyPair.privateKey, // 签名者私钥
    certificate: certOrCertPem, // 签名者证书
    digestAlgorithm: forge.pki.oids.sha256, // 摘要算法
    authenticatedAttributes: [{
        type: forge.pki.oids.contentType,
        value: forge.pki.oids.data
    }, {
        type: forge.pki.oids.messageDigest //值将在签名时自动填充
    }, {
        type: forge.pki.oids.signingTime,
        value: new Date()
    }]
});

signedData.sign({ detached: true });

const signedPem = pkcs7.messageToPem(signedData);
console.log('签名后的 PEM 格式数据:', signedPem);

const receivedSignedData = pkcs7.messageFromPem(signedPem);
const verifyResult = receivedSignedData.verify([signerCert]); #"node-forge": "^1.3.3" 暂未实现 verify

2.信封加密(Enveloped Data)

javascript 复制代码
import forge from 'node-forge';


const pkcs7 = forge.pkcs7;
const pki = forge.pki;

const recipientKeyPair = pki.rsa.generateKeyPair(2048);

//证书相关文档,教程 "八、X.509数字证书"
const recipientCert = pki.createCertificate();
recipientCert.publicKey = recipientKeyPair.publicKey;
recipientCert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16));
recipientCert.validity.notBefore = new Date();
recipientCert.validity.notAfter = new Date();
recipientCert.validity.notAfter.setFullYear(recipientCert.validity.notBefore.getFullYear() + 1);
// 设置证书主体/签发者(自签名)
const attrs = [{ name: 'commonName', value: 'Signer CA' }];
recipientCert.setSubject(attrs);
recipientCert.setIssuer(attrs);
recipientCert.sign(recipientKeyPair.privateKey, forge.md.sha256.create());

const envelopedData = pkcs7.createEnvelopedData();
envelopedData.content = forge.util.createBuffer('需要签名的敏感数据:用户订单号 #123456', 'utf8');
// 添加接收者(官网示例中的 recipient 对应的证书)
envelopedData.addRecipient(recipientCert);
// 加密消息(生成信封数据)
envelopedData.encrypt();

const pem = pkcs7.messageToPem(envelopedData);
console.log('=== 官网示例:加密后的 PEM 数据 ===\n', pem);


const receivedEnvelopedData = pkcs7.messageFromPem(pem);
// const recipient = receivedEnvelopedData.findRecipient(recipientCert);
// 解密消息
receivedEnvelopedData.decrypt(receivedEnvelopedData.recipients[0], recipientKeyPair.privateKey);
console.log('\n=== 官网示例:解密后的消息 ===\n', receivedEnvelopedData.content?.toString());

3.forge.pkcs7对象

函数名 描述 参数说明 返回值说明
createSignedData 创建一个空的PKCS#7签名数据(PkcsSignedData)对象,用于构建带签名的PKCS#7消息,支持添加证书、签名者并生成数字签名 无参数 PkcsSignedData- PKCS#7签名数据对象
createEnvelopedData 创建一个空的PKCS#7信封数据(PkcsEnvelopedData)对象,用于构建带加密内容的PKCS#7消息,支持添加接收者、加密/解密内容 无参数 PkcsEnvelopedData- PKCS#7信封数据对象
messageToPem 将PKCS#7签名数据对象转换为PEM格式字符串,便于存储和传输,可选指定每行最大字符数 1. msg: PkcsSignedData - 待转换的PKCS#7签名数据对象 2. maxline?: number - 可选,PEM字符串每行最大字符数(默认64) string- PEM格式的PKCS#7消息字符串
messageFromPem 从PEM格式字符串中解析出PKCS#7消息对象(支持签名数据或信封数据),返回包含原始捕获数据的包装对象 1. pem: pki.PEM - PEM格式的PKCS#7消息字符串 pem传PkcsSignedData数据返回PkcsSignedData 传PkcsEnvelopedData返回PkcsEnvelopedData
messageFromAsn1 从ASN.1结构对象中解析出PKCS#7消息对象(支持签名数据或信封数据),返回包含原始捕获数据的包装对象 1. asn: asn1.Asn1 - PKCS#7消息对应的ASN.1结构对象 asn传PkcsSignedData数据返回PkcsSignedData 传PkcsEnvelopedData返回PkcsEnvelopedData

4.PkcsSignedData对象

属性 类型 说明 参数说明 返回值说明
content string | util.ByteStringBuffer 待签名的原始数据,可直接传入字符串或forge字节缓冲区,签名后可随签名包一起传输 --- ---
contentInfo { value: any[] } PKCS#7内容信息对象,存储原始数据的类型、格式等元数据,通常由框架自动填充,无需手动配置 --- ---
certificates pki.Certificate[] 存储与签名相关的证书数组(如签名者证书、CA证书链),用于验证签名时确认签名者身份合法性 --- ---
addCertificate Function 向签名数据对象中添加证书,支持传入证书对象/PEM格式的证书字符串,用于绑定签名者身份凭证 certificate: pki.Certificate(证书对象)/ string(PEM格式证书字符串) void(无返回值)
addSigner Function 配置签名者信息,为后续生成数字签名提供必要参数(私钥、证书、摘要算法等) options配置项: 1. key: 签名者私钥(pki.rsa.PrivateKey对象/PEM格式私钥字符串) 2. certificate: 签名者证书(pki.Certificate对象/PEM格式证书字符串) 3. digestAlgorithm: 摘要算法OID(如forge.pki.oids.sha256) 4. authenticatedAttributes?: 可选认证属性数组,包含内容类型、消息摘要、签名时间等附加信息 void(无返回值)
sign Function 生成PKCS#7数字签名,将原始数据、签名者信息、证书打包为签名包 options?: 可选配置对象 detached: boolean(是否生成分离式签名,true=签名与原始数据分离,false=签名包含原始数据,默认false) void(无返回值)
toAsn1 Function 将PKCS#7签名数据对象转换为ASN.1结构对象,用于后续编码为PEM或DER格式进行存储/传输 --- ---

5.PkcsEnvelopedData对象

属性 类型 说明 参数说明 返回值说明
content string | util.ByteStringBuffer 待加密的原始敏感数据,或解密后还原的原始数据,支持字符串或forge字节缓冲区格式 --- ---
recipients Recipient[] 存储所有授权接收者的信息数组,每个接收者对应一套加密的会话密钥和身份信息,仅这些接收者可解密数据 --- ---
addRecipient Function 向授权接收者列表中添加新的接收者,仅该接收者可通过自身私钥解密密信数据 certificate: pki.Certificate(接收者的X.509证书对象,用于提取公钥加密会话密钥) void(无返回值)
encrypt Function 执行PKCS#7信封加密流程,生成包含加密数据和加密会话密钥的完整加密密信 1. key?: util.ByteStringBuffer(可选,对称加密使用的会话密钥,不传入则自动生成随机密钥) 2. cipher?: OID(可选,对称加密算法的OID,不传入默认使用AES-256-CBC) void(无返回值)
findRecipient Function 根据接收者的X.509证书,查找对应的Recipient接收者对象(通过证书的签发者和序列号匹配) cert: pki.Certificate(用于匹配接收者的X.509证书对象) Recipient对象 • version:接收者信息版本号,通常为0,保障格式解析兼容 • issuer:接收者证书签发者身份字段数组,用于匹配证书身份 • serialNumber:接收者证书唯一十六进制序列号,与issuer共同标识证书 • encryptedContent:接收者对应的加密会话密钥及算法元数据集合 • encryptedContent.algorithm:加密会话密钥的非对称加密算法OID • encryptedContent.parameter:非对称加密算法参数,通常为空或默认值 • encryptedContent.content:用接收者公钥加密后的对称会话密钥字节数据
decrypt Function 执行PKCS#7信封解密流程,还原原始敏感数据(先通过私钥解密会话密钥,再用会话密钥解密数据) 1. recipient: Recipient(待使用的接收者对象,需与私钥对应) 2. privKey: pki.rsa.PrivateKey(接收者的RSA私钥对象,用于解密会话密钥) void(无返回值)
toAsn1 Function 将PKCS#7信封数据对象转换为ASN.1结构对象,用于后续编码为PEM或DER格式进行存储与传输 --- asn1.Asn1(转换后的ASN.1结构对象)

十一、公钥基础设施 - PKCS#8 (私钥加密)

PKCS#8 是公钥基础设施下的规范之一,核心是私钥的加密存储格式,支持通过对称加密的方式保护私钥安全。

优点

  • 统一私钥存储格式:支持 RSA、ED25519 等多种算法;
  • 私钥安全保护性强:通过加密方式提升私钥存储的安全性。

缺点

  • 功能单一:仅用于私钥存储,无其他扩展安全能力。

适用场景

  • 加密库 / 系统的私钥安全存储:如 RSA 私钥、ED25519 私钥的加密存储;
  • 密钥管理系统:用于密钥管理平台中私钥的安全管理。
javascript 复制代码
import forge from 'node-forge';

let pki = forge.pki;
let sha1 = forge.md.sha1.create();
sha1.update('hello world', 'utf8');

// 生成 RSA 2048 位密钥对(原始私钥为 PKCS#1 格式)
const keypair = pki.rsa.generateKeyPair(2048);

// =========================  将原始 RSA 私钥(PKCS#1 格式)转换为标准 PKCS#8 格式的私钥 PEM 字符串 ========================
let privateKeyPEM = pki.privateKeyToPem(keypair.privateKey); // 私钥对象 → PKCS#8 格式 PEM 字符串(默认生成 PKCS#8,兼容性更强)
let pemPrivateKey = pki.privateKeyFromPem(privateKeyPEM); // PKCS#8 PEM 字符串 → 私钥对象(反序列化)
console.log('PEM私钥是否还原:', keypair.privateKey.sign(sha1) === pemPrivateKey.sign(sha1));

// =========================  将原始 RSA 私钥(PKCS#1 格式)转换为标准 PKCS#8 格式的私钥 ASN.1 对象 ========================
const privateKeyAsn1 = pki.privateKeyToAsn1(keypair.privateKey); // 私钥对象 → PKCS#1 格式 ASN.1 对象(仅包含 RSA 私钥参数)
let asn1PrivateKey = pki.privateKeyFromAsn1(privateKeyAsn1); // PKCS#1 ASN.1 对象 → 私钥对象(反序列化)
console.log('Asn1私钥是否还原:', keypair.privateKey.sign(sha1) === asn1PrivateKey.sign(sha1));

// =========================  将原始 RSA 私钥(PKCS#1 格式)转换为标准 PKCS#8 格式的私钥 PEM 字符串 ========================
let privateKeyInfoAsn1 = pki.wrapRsaPrivateKey(privateKeyAsn1); // 包装:PKCS#1 ASN.1 对象 → PKCS#8 格式 PrivateKeyInfo ASN.1 对象(添加算法标识等元数据,通用格式)
let pemAsn1 = pki.privateKeyInfoToPem(privateKeyInfoAsn1); // 转换:PKCS#8 ASN.1 对象 → PKCS#8 格式 PEM 字符串(头部:BEGIN PRIVATE KEY)
let pemPrivateKey2 = pki.privateKeyFromPem(pemAsn1); // 解析:PKCS#8 PEM 字符串 → 私钥对象
console.log('PEM私钥是否还原(RSA私钥):', keypair.privateKey.sign(sha1) === pemPrivateKey2.sign(sha1));

// =========================  私钥加密保护、序列化、解密还原流程(核心优化部分) ========================
const password = 'myCustomPasswordHere';
/**
 * 1. 加密 PKCS#8 私钥信息(生成带密码保护的私钥对象)
 *  - 输入:PKCS#8 私钥ASN.1对象、密码、加密算法配置
 *  - 输出:EncryptedPrivateKeyInfo ASN.1 对象(含加密算法、加密后的私钥数据)
 *  - 算法:aes256 安全性最高,推荐生产环境使用
 */
let encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo(
    privateKeyInfoAsn1, // PKCS#8 格式私钥ASN.1对象(明文)
    password, // 私钥保护密码(建议生产环境使用高强度密码)
    { algorithm: 'aes256' } // 对称加密算法配置,支持 aes128/aes192/aes256/3des
);

/**
 * 2. 解密加密私钥信息(还原明文 PKCS#8 私钥对象)
 *  - 输入:加密后的EncryptedPrivateKeyInfo对象、加密密码
 *  - 输出:原始 PKCS#8 格式 PrivateKeyInfo ASN.1 对象(明文)
 *  - 注意:密码错误会抛出异常,需添加异常捕获
 */
const privateKeyInfo = pki.decryptPrivateKeyInfo(
    encryptedPrivateKeyInfo, // 加密后的私钥对象
    password // 对应加密时的密码
);

/**
 * 3. 加密私钥对象 → 加密私钥 PEM 字符串(序列化,便于存储/传输)
 *  - 输出 PEM 头部:-----BEGIN ENCRYPTED PRIVATE KEY-----
 *  - 该格式是标准加密私钥格式,可被大多数加密库识别
 */
let encryptedPrivatePem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo);

/**
 * 4. 加密私钥 PEM → 加密私钥对象(反序列化,从存储/传输中还原)
 *  - 解析 PEM 字符串,还原为 EncryptedPrivateKeyInfo ASN.1 对象
 */
encryptedPrivateKeyInfo = pki.encryptedPrivateKeyFromPem(encryptedPrivatePem);

/**
 * 5. (可选)直接加密 RSA 私钥(PKCS#1 格式)为加密 PEM
 *  - encryptRsaPrivateKey:专门用于 RSA 私钥加密,默认生成 PKCS#8 加密格式
 *  - legacy: true:生成传统 PKCS#1 加密格式(兼容老系统,不推荐现代环境使用)
 */
const encryptedRsaPrivatePem = pki.encryptRsaPrivateKey(keypair.privateKey, password);

/**
 * 6. 解密 RSA 加密私钥 PEM → 原始 RSA 私钥对象
 *  - 输入:加密私钥 PEM 字符串、密码
 *  - 输出:RSA 私钥对象(可直接用于签名/解密操作)
 *  - 注意:需确保密码与加密时一致,且 PEM 格式正确
 */
const decryptedRsaPrivateKey = pki.decryptRsaPrivateKey(encryptedRsaPrivatePem, password);

/**
 * 7. 从 RSA 私钥对象中提取公钥(通过私钥的 n 模和 e 公钥指数生成)
 *  - 公钥可公开,用于加密数据或验证私钥签名
 */
const publicKey = pki.setRsaPublicKey(decryptedRsaPrivateKey.n, decryptedRsaPrivateKey.e);

/**
 * 8. 验证最终还原的私钥功能一致性(签名对比)
 */
const finalSign = decryptedRsaPrivateKey.sign(sha1);
const originalSign = keypair.privateKey.sign(sha1);
console.log('=== 最终私钥还原验证 ===', finalSign === originalSign ? '✅ 私钥功能完全一致' : '❌ 私钥还原失败');

十二、公钥基础设施 - PKCS#10 (证书签名请求)

PKCS#10 是公钥基础设施下的规范之一,核心是证书签名请求(CSR)格式,用于向 CA(证书颁发机构)申请数字证书。

优点

  • 是 CA 签发证书的标准输入格式,通用性强;
  • 包含公钥和身份信息,能明确证书申请的主体信息。

缺点

  • 仅用于证书申请,功能较为单一。

适用场景

  • 向 CA 申请数字证书:如网站申请 HTTPS 证书;
  • 企业 PKI 体系的证书签发流程:支撑企业内部证书的申请与发放。
javascript 复制代码
import forge from 'node-forge';

const pki = forge.pki;

//证书相关文档,教程 "八、X.509数字证书"
const kwyPair = pki.rsa.generateKeyPair(2048);
let csr = forge.pki.createCertificationRequest();
csr.publicKey = kwyPair.publicKey;
csr.setSubject([
    { name: 'commonName', value: 'example.org' },
    { name: 'countryName', value: 'US' },
    { shortName: 'ST', value: 'Virginia' },
    { name: 'localityName', value: 'Blacksburg' },
    { name: 'organizationName', value: 'Test' },
    { shortName: 'OU', value: 'Test' }
]);

csr.setAttributes([
    { name: 'challengePassword', value: 'password' },
    { name: 'unstructuredName', value: 'My Company, Inc.' },
    {
        name: 'extensionRequest',
        extensions: [
            {
                name: 'subjectAltName',
                altNames: [
                    { type: 2, value: 'test.domain.com' },
                    { type: 2, value: 'other.domain.com' },
                    { type: 2, value: 'www.domain.net' }
                ]
            }
        ]
    }
]);

csr.sign(kwyPair.privateKey);

const verified = csr.verify();
console.log('verified:', verified);
const pem = forge.pki.certificationRequestToPem(csr);
console.log('crs转换pem:', pem);
console.log('pem转换后边的crs:', forge.pki.certificationRequestFromPem(pem));

console.log('challengePassword:', csr.getAttribute({ name: 'challengePassword' }));
console.log('extensionRequest:', csr.getAttribute({ name: 'extensionRequest' }).extensions);

十三、公钥基础设施 - PKCS#12 (打包私钥、公钥证书、CA 证书)

PKCS#12 是公钥基础设施下的规范之一,核心用于将私钥、公钥证书、CA 证书链打包为单个文件(如.p12/.pfx 格式)。

优点

  • 简化密钥 / 证书的传输与存储,整合多类密钥证书资源;
  • 支持密码保护打包文件,提升打包内容的安全性。

缺点

  • 格式兼容性存在差异,不同系统间解析可能出现错误;
  • 大文件打包时效率较低。

适用场景

  • 密钥 / 证书的备份与传输:如 HTTPS 证书对应的.pfx 文件;
  • 客户端证书的分发:用于向客户端传递加密所需的证书与密钥。
函数名 说明 参数说明 返回值类型
pkcs12FromAsn1 将PKCS#12格式的ASN.1结构化对象解析为可操作的Pkcs12Pfx对象,支持密码解密和严格/非严格解析模式,用于解析P12/PFX文件内容 1. obj: any - PKCS#12格式的ASN.1结构化对象 2. strict?: boolean - 可选,是否启用严格解析模式(默认true,非严格模式可兼容轻微格式错误) 3. password?: string - 可选,P12文件解密密码 Pkcs12Pfx:包含P12内容的可操作对象,包含安全内容和筛选方法 1. Pkcs12Pfx.version:P12/PFX格式版本号,保障解析兼容性 2. Pkcs12Pfx.safeContents:安全内容容器数组,每个容器结构: • encrypted:该容器是否加密(true=加密,false=明文) • safeBags:存储私钥/证书的安全袋数组 3. Pkcs12Pfx.getBags(filter):按筛选条件(本地密钥ID/友好名称等)过滤安全袋,返回分类匹配结果 4. Pkcs12Pfx.getBagsByFriendlyName(friendlyName, bagType):按友好名称+袋类型精准筛选,返回匹配的安全袋数组 5. Pkcs12Pfx.getBagsByLocalKeyId(localKeyId, bagType):按本地密钥ID+袋类型精准筛选,返回匹配的安全袋数组
toPkcs12Asn1 根据私钥、证书(链)和配置,构建PKCS#12格式的ASN.1结构化对象,生成P12/PFX文件的核心方法,后续可转为DER二进制格式保存 1. key: 用于传入生成P12容器的RSA私钥对象,传入有效pki.rsa.PrivateKey时,私钥会被加密存入P12;传入null时,P12仅存储证书,不包含私钥(极少场景使用) 2. cert: 用于传入要存入P12的X.509证书,支持单个pki.Certificate主证书,也支持证书数组(主证书+CA证书链,用于验证证书有效性) 3. password: 用于设置P12容器的解密密码,传入非空字符串时,P12内容会被密码加密(解密需对应密码);传入null时,P12无密码保护(明文存储,不推荐生产环境);传入空字符串,适配OpenSSL空密码生成的P12场景 4. options配置项: • lgoritnm:P12加密算法,默认aes256(最高安全)、3des兼容老系统 • count:PBKDF2迭代次数,默认1000,越高越安全但速度越慢 • saltSize:密码盐值大小,默认8字节,防彩虹表攻击 • useMac:是否启用MAC校验,默认true,验证P12是否被篡改 • localKeyId:本地密钥ID(十六进制),用于关联私钥与证书 • friendlyName:私钥/证书友好名称,便于工具识别和筛选 • generateLocalKeyId:是否自动生成密钥ID,默认false,true无需手动配置 返回asn1.Asn1对象
generateKey 基于密码、盐值等参数,通过密钥派生函数(PBKDF2)生成加密/解密所需的密钥,是P12文件加密和解密的底层辅助方法,无需手动调用(内部自动使用) 1. password: 派生密钥的原始密码,null/undefined表示无密码,非空字符串为有效密码 2. salt: 盐值缓冲区,用于增强密码安全性,防止彩虹表攻击 3. id: 密钥用途标识字节,区分私钥/证书等不同用途的加密密钥 4. iter: 密钥派生迭代次数,数值越高,密码破解难度越大 5. n: 要生成的密钥字节长度,决定密钥的强度 6. md: 可选消息摘要对象,用于密钥派生计算,默认使用对应加密算法的默认摘要 返回util.ByteStringBuffer

十四、公钥基础设施 - ASN.1

ASN.1 是公钥基础设施下的抽象语法标记,核心用于描述密码学数据(如证书、密钥)的结构,常用 DER/PEM 编码格式。

优点

  • 是 X.509、PKCS 等密码学标准的基础编码格式,通用性极强;
  • 跨平台兼容性强,可在不同系统间稳定传输数据。

缺点

  • 可读性差(如二进制 DER 编码),非专业工具难以直接解析;
  • 解析与序列化的复杂度较高,技术实现成本大。

适用场景

  • 密码学数据的标准化存储 / 传输:如证书的 DER/PEM 格式;
  • 加密库间的数据交互:保障不同加密工具间的数据兼容。
函数名 函数描述 参数说明 返回值类型
create 创建符合ASN.1规范的结构化对象,用于构建自定义ASN.1数据结构 1. tagClass: asn1.Class - ASN.1标签类 2. type: asn1.Type - ASN.1数据类型 3. constructed: boolean - 是否为构造化类型 4. value: Bytes | Asn1[] asn1.Asn1
fromDer 将DER二进制编码数据解析为可操作的ASN.1结构化对象,用于读取ASN.1格式数据 bytes: Bytes | util.ByteBuffer - 承载DER编码数据的载体 strict: boolean - 解析模式开关 asn1.Asn1
toDer 与fromDer功能相反,将内存中的ASN.1对象转换为标准DER二进制格式,该格式是ASN.1数据的实际存储/传输格式(如生成证书文件、P12二进制数据)。返回的util.ByteStringBuffer可通过getBytes()方法转为字节字符串 obj: asn1.Asn - 待转换的ASN.1结构化对象 util.ByteStringBuffer
oidToDer 专门用于OID类型的DER编码转换,仅生成OID本身的二进制数据,不包含ASN.1标签和长度字段,通常用于构建AlgorithmIdentifier等包含OID的ASN.1节点 oid: OID - 点分格式的OID字符串(如"1.2.840.113549.1.1.1",对应RSA加密算法) util.ByteStringBuffer
derToOid 将DER编码的OID二进制数据转换为点分格式的OID字符串,用于识别算法/对象类型 bytes: Bytes | util.ByteStringBuffer util.ByteStringBuffer
integerToDer 针对ASN.1 INTEGER类型的专用编码方法,将JavaScript普通整数转为符合DER规范的二进制数据,适用于构建证书序列号、公钥指数等整数类型字段 int: number - 需要转换的整数数值 util.ByteStringBuffer
derToInteger 将DER编码的整数二进制数据转换为普通整数,用于解析ASN.1 INTEGER类型节点的值 bytes: Bytes | util.ByteStringBuffer util.ByteStringBuffer:DER编码的整数二进制数据
dateToUtcTime 将日期转换为ASN.1 UTCTIME类型的字节数据,用于构建证书有效期等时间字段 date: 需要转换的日期对象或日期字符串(需符合UTC时间格式要求) util.ByteStringBuffer
utcTimeToDate 用于解析证书等ASN.1数据中的UTCTIME类型时间字段,将字节/字符串格式的时间转换为JavaScript Date对象,方便进行时间比较和格式化展示 bytes: Bytes - ASN.1 UTCTIME类型的字节数据 Date:转换后的日期
dateToGeneralizedTime 将日期转换为ASN.1 GENERALIZEDTIME类型的字节数据,用于构建长期有效时间字段 date: 需要转换的日期 string:需要转换的日期对象或日期字符串(支持更宽泛的时间范围,优于UTCTIME)
generalizedTimeToDate 用于解析ASN.1数据中的GENERALIZEDTIME类型时间字段,支持更宽泛的时间范围,转换为JavaScript Date对象,适用于读取长期有效数据的时间信息 bytes: Bytes - ASN.1 GENERALIZEDTIME类型的字节数据 Date:转换后的日期

十五、SSH传输协议

javascript 复制代码
import forge from 'node-forge';

// 1. 生成RSA密钥对(基础依赖)
const keyPair = forge.pki.rsa.generateKeyPair(2048);
const privateKey = keyPair.privateKey;
const publicKey = keyPair.publicKey;
const passphrase = '123456'; // 密钥加密密码
const comment = 'test@example.com'; // 密钥注释

// 2. 生成Putty PPK格式私钥
const ppkPrivateKey = forge.ssh.privateKeyToPutty(privateKey, passphrase, comment);
console.log('✅ Putty PPK私钥:\n', ppkPrivateKey);
// 可写入文件:fs.writeFileSync('id_rsa.ppk', ppkPrivateKey);

// 3. 生成OpenSSH格式公钥
const openSshPublicKey = forge.ssh.publicKeyToOpenSSH(publicKey, comment);
console.log('\n✅ OpenSSH公钥:\n', openSshPublicKey);
// 可写入文件:fs.writeFileSync('id_rsa.pub', openSshPublicKey);

// 4. 生成OpenSSH格式私钥(加密)
const openSshPrivateKey = forge.ssh.privateKeyToOpenSSH(privateKey, passphrase);
console.log('\n✅ OpenSSH加密私钥:\n', openSshPrivateKey);
// 可写入文件:fs.writeFileSync('id_rsa', openSshPrivateKey);

// 5. 生成原始字节缓冲区格式公钥指纹
const fingerprintBuffer = forge.ssh.getPublicKeyFingerprint(publicKey);
console.log('\n✅ 原始指纹字节缓冲区:', fingerprintBuffer);
console.log('✅ 原始指纹转十六进制:', fingerprintBuffer.toHex());

// 6. 生成格式化(十六进制+冒号分隔)公钥指纹
const formattedFingerprint = forge.ssh.getPublicKeyFingerprint(publicKey, {
    encoding: 'hex',
    delimiter: ':'
});
console.log('\n✅ 格式化公钥指纹:', formattedFingerprint);
函数名称 函数说明 参数说明 返回值类型
privateKeyToOpenSSH 将RSA私钥编码为OpenSSH格式文件,支持可选密码加密,适配OpenSSH环境使用 1. privateKey: pki.rsa.PrivateKey - 待转换的RSA私钥对象 2. passphrase?: string - 可选,用于加密私钥的密码,不传则生成无密码OpenSSH私钥 string(OpenSSH格式私钥字符串)
privateKeyToPutty 将RSA私钥编码(并可选加密)为Putty专用PPK格式文件,适配Putty系列工具使用 1. privateKey: pki.rsa.PublicKey - 待转换的RSA私钥对象 2. passphrase?: string - 可选,用于加密PPK文件的密码,不传则生成无密码PPK文件 3. comment?: string - 可选,密钥注释,便于识别密钥用途 string(Putty PPK格式字符串)
publicKeyToOpenSSH 将RSA公钥编码为OpenSSH格式文件,可添加注释,适配OpenSSH/SSH客户端使用 1. publicKey: pki.rsa.PublicKey - 待转换的RSA公钥对象 2. comment?: string - 可选,密钥注释(通常为"用户名@主机名"格式) string | pki.PEM
getPublicKeyFingerprint 获取指定SSH公钥的指纹,支持自定义编码、分隔符和摘要算法,用于密钥合法性校验 1. publicKey: pki.rsa.PublicKey - 待生成指纹的RSA公钥对象 2. options?: FingerprintOptions - 可选配置对象,包含: • options.delimiter: 十六进制编码输出时,字节之间使用的分隔符(可选) • options.encoding: 输出编码格式,不指定则返回ByteStringBuffer(可选,支持"hex"/"binary") • options.md: 计算指纹的摘要算法,不指定默认使用md.md5(可选) util.ByteStringBuffer | Hex | string

十六、TLS传输协议

函数名称 函数说明 参数说明 返回值类型
createSessionCache 创建TLS会话缓存对象,用于存储和复用TLS会话,提升连接建立效率 SessionCache:缓存对象 • SessionCache.cache:存储TLS会话的键值对集合,以会话ID为键,Session对象为值 • SessionCache.capacity:会话缓存的最大容量,限制可存储的会话数量 • SessionCache.order:会话缓存的存储顺序数组(十六进制格式),用于管理缓存淘汰逻辑 • SessionCache.getSession(sessionId):根据会话ID从缓存中获取对应的TLS会话对象 • SessionCache.setSession(sessionId,session):将指定会话ID和对应的TLS会话对象存入缓存 SessionCache
createConnection 创建TLS连接对象,用于构建TLS客户端/服务器连接,处理TLS握手与数据传输 options: 配置项 • options.server:是否为TLS服务器端连接(可选) • options.sessionId:TLS会话ID(可选,可为null) • options.caStore:CA证书仓库或证书数组,用于验证对方证书(可选) • options.sessionCache:TLS会话缓存或会话键对,用于会话复用(可选) • options.cipherSuites:支持的TLS加密套件数组(可选) • options.virtualHost:虚拟主机名(可选,用于SNI扩展) • options.verifyClient:是否验证客户端证书(仅服务器端有效,可选) • options.connected(conn: Connection):TLS连接建立成功后的回调函数 • options.verify(conn: Connection, verified: Verified, depth: number, certs: pki.Certificate[]):证书验证回调函数,用于自定义证书校验逻辑(可选) • options.getCertificate(conn: Connection, hint: CertificateRequest | string[]):获取证书的回调函数,返回PEM格式证书(可选) • options.getPrivateKey(conn: Connection, certificate: pki.Certificate):获取证书对应私钥的回调函数,返回PEM格式私钥(可选) • options.getSignature(conn: Connection, bytes: Bytes, callback: (conn: Connection, bytes: Bytes) => void):生成数字签名的回调函数,处理签名逻辑(可选) • options.tlsDataReady(conn: Connection):TLS加密数据就绪后的回调函数 • options.dataReady(conn: Connection):解密后的应用层数据就绪后的回调函数 • options.heartbeatReceived(conn: Connection, payload: util.ByteBuffer):收到TLS心跳消息后的回调函数(可选) • options.closed(conn: Connection):TLS连接关闭后的回调函数 • options.error(conn: Connection):TLS连接发生错误后的回调函数 • options.deflate(inBytes: Bytes):数据压缩回调函数,对发送数据进行压缩(可选) • options.inflate(inBytes: Bytes):数据解压回调函数,对接收数据进行解压(可选) Connection对象 • Connection.version:TLS协议版本信息 • Connection.entity:TLS连接类型(客户端/服务器端) • Connection.sessionId:TLS会话ID,可为null • Connection.caStore:CA证书仓库,用于验证对方证书 • Connection.sessionCache:TLS会话缓存,可为null • Connection.cipherSuites:支持的TLS加密套件数组 • Connection.connected(conn: Connection):连接建立成功后的回调函数 • Connection.virtualHost:虚拟主机名(用于SNI扩展) • Connection.verifyClient:是否验证客户端证书(仅服务器端有效) • Connection.verify(conn: Connection, verified: Verified, depth: number, certs: pki.Certificate[]):自定义证书验证的回调函数 • Connection.getCertificate:获取证书的回调函数(conn: Connection, hint: CertificateRequest | string[]) => pki.PEM | readyState.pki.PEM),可为null • Connection.getPrivateKey:获取证书对应私钥的回调函数(conn: Connection, certificate: pki.Certificate) => pki.PEM),可为null • Connection.getSignature:生成数字签名的回调函数(conn: Connection, bytes: Bytes, callback: (conn: Connection, bytes: Bytes) => void),可为null • Connection.input:接收的原始数据字节缓冲区 • Connection.tlsData:待发送的TLS加密数据字节缓冲区 • Connection.data:解密后的应用层数据字节缓冲区 • Connection.tlsDataReady(conn: Connection):TLS加密数据就绪后的回调函数 • Connection.dataReady(conn: Connection):应用层数据就绪后的回调函数 • Connection.heartbeatReceived:收到TLS心跳消息后的回调函数(conn: Connection, payload: util.ByteBuffer) => void;),可为undefined • Connection.closed:连接关闭后的回调函数(conn: Connection) => void;) • Connection.error:连接发生错误后的回调函数(conn: Connection, error: TLSerror) => void;) • Connection.deflate:数据压缩函数((inBytes: Bytes) => Bytes),可为null • Connection.inflate:数据解压函数((inBytes: Bytes) => Bytes),可为null • Connection.reset(clearFail?: boolean):重置TLS连接状态的方法 • Connection.record:当前处理的TLS记录,可为null • Connection.session:当前TLS会话对象,可为null • Connection.peerCertificate:对方的证书对象,可为null • Connection.state:连接状态(包含待处理和当前状态) • Connection.expect:期望接收的数据长度 • Connection.fragmented:分片的TLS记录,可为null • Connection.records:待处理的TLS记录数组 • Connection.open:连接是否处于打开状态 • Connection.handshakes:已完成的握手次数 • Connection.handshaking:是否正在进行TLS握手 • Connection.isConnected:是否已成功建立连接 • Connection.fail:连接是否已失败 • Connection.handshake(sessionId?: Bytes | null):执行TLS握手的方法 • Connection.process(data: Bytes):处理接收数据的方法,返回处理的字节数 • Connection.prepare(data: Bytes):准备发送数据的方法,返回是否准备成功 • Connection.prepareHeartbeatRequest(payload: Bytes | util.ByteBuffer, payloadLength?: number):准备TLS心跳请求的方法,返回是否准备成功 • Connection.close(clearFail?: boolean):关闭TLS连接的方法,返回连接对象
prf_tls1 实现TLS 1.0伪随机函数(PRF),用于从密钥材料生成指定长度的密钥数据 1. secret: string:密钥种子(共享密钥材料) 2. label: string:标识标签(用于区分不同用途的密钥) 3. seed: string:随机种子(用于增加随机性) 4. length: number:需要生成的密钥数据长度 util.ByteBuffer(生成的密钥数据字节缓冲区)
hmac_sha1 基于SHA1算法生成TLS记录的HMAC消息认证码,用于验证记录数据的完整性和真实性 1. key: HMAC-SHA1加密密钥,支持字符串、字节数组或字节缓冲区格式 2. seqNum: TLS记录序列号,64位整数(以双元素数组表示) 3. record: 待生成认证码的TLS记录对象 Bytes

十七、forge.pki 通用函数

函数名 说明 参数说明 返回值类型
pemToDer 将PEM格式数据转换为DER二进制编码数据,去除PEM头部、尾部和换行符 pem: PEM - PEM格式字符串(带头部尾部标识,如私钥/证书PEM) util.ByteStringBuffer
privateKeyToPem 将RSA私钥对象转换为标准PEM格式字符串,支持指定每行最大长度 1. key: PrivateKey - RSA私钥对象 2. maxline?: number - 可选,每行最大字符数,默认按标准拆分 PEM
privateKeyInfoToPem 将私钥信息的ASN.1对象转换为PEM格式字符串,支持指定每行最大长度 1. key: asn1.Asn1 - 私钥信息的ASN.1结构化对象 2. maxline?: number - 可选,每行最大字符数,默认按标准拆分 PEM
publicKeyToPem 将RSA公钥对象转换为X.509标准公钥PEM格式字符串,支持指定每行最大长度 1. key: PublicKey - RSA公钥对象 2. maxline?: number - 可选,每行最大字符数,默认按标准拆分 PEM
publicKeyToRSAPublicKeyPem 将RSA公钥对象转换为PKCS#1格式公钥PEM字符串,支持指定每行最大长度 1. key: PublicKey - RSA公钥对象 2. maxline?: number - 可选,每行最大字符数,默认按标准拆分 PEM
publicKeyFromPem 从PEM格式字符串中解析并获取RSA公钥对象 pem: PEM - X.509或PKCS#1格式的公钥PEM字符串 rsa.PublicKey
privateKeyFromPem 从无加密PEM格式字符串中解析并获取RSA私钥对象 pem: PEM - 无加密的RSA私钥PEM字符串(PKCS#1或PKCS#8格式) rsa.PrivateKey
decryptPrivateKeyInfo 使用密码解密私钥信息的ASN.1对象,获取明文私钥ASN.1结构 1. obj: asn1.Asn1 - 加密后的私钥信息ASN.1对象 2. password: string - 解密密码 asn1.Asn1
encryptPrivateKeyInfo 使用密码加密私钥信息的ASN.1对象,支持自定义加密选项 1. obj: asn1.Asn1 - 明文私钥信息ASN.1对象 2. password: string - 加密密码 3. options?: EncryptionOptions - 可选,加密配置(如加密算法、迭代次数等) asn1.Asn1
encryptedPrivateKeyFromPem 从加密私钥PEM格式字符串中解析出加密私钥的ASN.1对象 pem: PEM - 加密的RSA私钥PEM字符串(如PKCS#8加密私钥) asn1.Asn1
encryptedPrivateKeyToPem 将加密私钥的ASN.1对象转换为加密私钥PEM格式字符串 obj: asn1.Asn1 - 加密后的私钥信息ASN.1对象 PEM
decryptRsaPrivateKey 使用密码解密加密私钥PEM字符串,获取RSA私钥对象 1. pem: PEM - 加密的RSA私钥PEM字符串 2. password: string - 解密密码 rsa.PrivateKey
encryptRsaPrivateKey 使用密码加密RSA私钥对象,生成加密私钥PEM格式字符串,支持自定义加密选项 1. privateKey: PrivateKey - 明文RSA私钥对象 2. password: string - 加密密码 3. options?: EncryptionOptions - 可选,加密配置(如加密算法、迭代次数等) PEM
privateKeyFromAsn1 从私钥ASN.1对象中解析并获取RSA私钥对象 privateKey: asn1.Asn1 - 明文私钥的ASN.1结构化对象 rsa.PrivateKey
privateKeyToAsn1 将RSA私钥对象转换为私钥ASN.1结构化对象 privateKey: PrivateKey - RSA私钥对象 asn1.Asn1
publicKeyFromAsn1 从公钥ASN.1对象中解析并获取RSA公钥对象 publicKey: asn1.Asn1 - 公钥的ASN.1结构化对象(如SubjectPublicKeyInfo) rsa.PublicKey
publicKeyToAsn1 将RSA公钥对象转换为X.509标准公钥ASN.1对象(SubjectPublicKeyInfo) publicKey: PublicKey - RSA公钥对象 asn1.Asn1
publicKeyToRSAPublicKey 将RSA公钥对象转换为PKCS#1格式的公钥数据(兼容旧版格式) publicKey: PublicKey - RSA公钥对象 any(PKCS#1格式公钥数据)
setRsaPublicKey 为RSA公钥对象设置模(n)和公钥指数(e)参数,初始化公钥 继承自pki.rsa.setPublicKey,参数为模和公钥指数(具体同rsa.setPublicKey) void(无返回值,直接修改对象)
setRsaPrivateKey 为RSA私钥对象设置完整私钥参数,初始化私钥 继承自pki.rsa.setPrivateKey,参数为模、指数、私钥指数等(具体同rsa.setPrivateKey) void(无返回值,直接修改对象)
wrapRsaPrivateKey 将PKCS#1格式私钥ASN.1对象包装为PKCS#8格式私钥ASN.1对象 privateKey: asn1.Asn1 - PKCS#1格式私钥ASN.1对象 asn1.Asn1(PKCS#8格式私钥对象)
getPublicKeyFingerprint 生成公钥指纹,返回字节缓冲区格式(默认SHA-1算法) 1. publicKey: PublicKey - RSA公钥对象 2. options: 配置项,选择一种: • 【ByteBufferFingerprintOptions】:可选,指纹配置(算法、编码等),返回字节缓冲区 • 【HexFingerprintOptions】:必选,指纹配置(指定返回十六进制格式) • 【BinaryFingerprintOptions】:必选,指纹配置(指定返回字节字符串格式) util.ByteStringBuffer | Hex | Bytes

十八、 util.ByteStringBuffer

函数名 函数说明 参数说明 返回值类型
length 获取缓冲区中字节数据的总长度 无参数 number(字节长度)
isEmpty 判断缓冲区是否为空(无有效字节数据) 无参数 boolean(空返回true,非空返回false)
putByte 向缓冲区末尾写入一个字节数据 byte: Byte - 待写入的单个字节(0-255整数) ByteStringBuffer(当前实例,支持链式调用)
fillWithByte 向缓冲区末尾写入指定数量的重复字节 1. byte: Byte - 填充的字节值 2. n: number - 填充的字节数量 ByteStringBuffer(当前实例,支持链式调用)
putBytes 向缓冲区末尾写入一组字节字符串数据 bytes: Bytes - 待写入的字节字符串 ByteStringBuffer(当前实例,支持链式调用)
putString 向缓冲区末尾写入普通字符串(按字符编码转换为字节) str: string - 待写入的普通字符串 ByteStringBuffer(当前实例,支持链式调用)
putInt16 向缓冲区末尾写入16位大端序整数 int: number - 待写入的16位整数 ByteStringBuffer(当前实例,支持链式调用)
putInt24 向缓冲区末尾写入24位大端序整数 int: number - 待写入的24位整数 ByteStringBuffer(当前实例,支持链式调用)
putInt32 向缓冲区末尾写入32位大端序整数 int: number - 待写入的32位整数 ByteStringBuffer(当前实例,支持链式调用)
putInt16Le 向缓冲区末尾写入16位小端序整数 int: number - 待写入的16位整数 ByteStringBuffer(当前实例,支持链式调用)
putInt24Le 向缓冲区末尾写入24位小端序整数 int: number - 待写入的24位整数 ByteStringBuffer(当前实例,支持链式调用)
putInt32Le 向缓冲区末尾写入32位小端序整数 int: number - 待写入的32位整数 ByteStringBuffer(当前实例,支持链式调用)
putInt 向缓冲区末尾写入指定位数的无符号整数 1. int: number - 待写入的整数 2. numOfBits: number - 整数的位数(如8、16、32等) ByteStringBuffer(当前实例,支持链式调用)
putSignedInt 向缓冲区末尾写入指定位数的有符号整数 1. int: number - 待写入的有符号整数 2. numOfBits: number - 整数的位数(如8、16、32等) ByteStringBuffer(当前实例,支持链式调用)
putBuffer 向缓冲区末尾写入另一个字节字符串缓冲区的数据 buffer: ByteStringBuffer - 待写入的其他ByteStringBuffer实例 ByteStringBuffer(当前实例,支持链式调用)
getByte 从缓冲区当前读取位置读取一个字节数据,并推进读取偏移量 无参数 number(读取的字节值,0-255)
getInt16 从缓冲区当前读取位置读取16位大端序整数,并推进读取偏移量 无参数 number(读取的16位整数)
getInt24 从缓冲区当前读取位置读取24位大端序整数,并推进读取偏移量 无参数 number(读取的24位整数)
getInt32 从缓冲区当前读取位置读取32位大端序整数,并推进读取偏移量 无参数 number(读取的32位整数)
getInt16Le 从缓冲区当前读取位置读取16位小端序整数,并推进读取偏移量 无参数 number(读取的16位整数)
getInt24Le 从缓冲区当前读取位置读取24位小端序整数,并推进读取偏移量 无参数 number(读取的24位整数)
getInt32Le 从缓冲区当前读取位置读取32位小端序整数,并推进读取偏移量 无参数 number(读取的32位整数)
getInt 从缓冲区当前读取位置读取指定位数的无符号整数,并推进读取偏移量 numOfBits: number - 待读取整数的位数(如8、16、32等) number(读取的无符号整数)
getSignedInt 从缓冲区当前读取位置读取指定位数的有符号整数,并推进读取偏移量 numOfBits: number - 待读取整数的位数(如8、16、32等) number(读取的有符号整数)
getBytes 从缓冲区当前读取位置读取指定数量的字节字符串,并推进读取偏移量 count?: number - 可选,读取的字节数量(不传则读取剩余所有字节) Bytes(读取的字节字符串)
bytes 读取缓冲区中指定数量的字节字符串(不改变读取偏移量,与getBytes区别) count?: number - 可选,读取的字节数量(不传则读取所有字节) Bytes(读取的字节字符串)
at 获取缓冲区中指定索引位置的字节数据(不改变读取偏移量) index: number - 字节索引(从0开始) Byte(指定位置的字节值,0-255)
setAt 修改缓冲区中指定索引位置的字节数据 1. index: number - 字节索引(从0开始) 2. byte: number - 新的字节值(0-255) ByteStringBuffer(当前实例,支持链式调用)
last 获取缓冲区中最后一个字节数据(不改变读取偏移量) 无参数 Byte(最后一个字节值,0-255)
copy 复制当前缓冲区的完整数据,创建一个新的ByteStringBuffer实例 无参数 ByteStringBuffer(新的实例副本)
compact 压缩缓冲区,移除已读取的字节数据,优化内存占用 无参数 ByteStringBuffer(当前实例,支持链式调用)
clear 清空缓冲区中的所有数据,重置读取偏移量 无参数 ByteStringBuffer(当前实例,支持链式调用)
truncate 截断缓冲区,保留未读取的字节数据,重置读取偏移量 无参数 ByteStringBuffer(当前实例,支持链式调用)
toHex 将缓冲区中的字节数据转换为十六进制字符串 无参数 Hex(十六进制格式字符串)
toString 将缓冲区中的字节数据转换为普通字符串(按字符编码解析) 无参数 string(解析后的普通字符串)

十九、工具函数

1.forge.util

函数名 函数说明 参数说明 返回值类型
fillString 生成由指定字符重复指定次数组成的字符串 1. char: string - 用于填充的单个字符 2. count: number - 字符重复的次数 string
xorBytes 对两个字节字符串进行按位异或运算,返回指定长度的结果字节字符串 1. bytes1: string - 第一个字节字符串 2. bytes2: string - 第二个字节字符串 3. count: number - 需要进行异或运算的字节长度 string(字节字符串)
hexToBytes 将十六进制字符串转换为字节字符串 hex: Hex - 待转换的十六进制字符串 Bytes
bytesToHex 将字节字符串转换为十六进制字符串 bytes: Bytes - 待转换的字节字符串 Hex
int32ToBytes 将32位整数转换为对应的字节字符串(大端序) int: number - 待转换的32位整数 Bytes
encode64 将字节字符串编码为Base64格式字符串,支持指定每行最大长度 1. bytes: Bytes - 待编码的字节字符串 2. maxline?: number - 可选,每行最大字符数(用于格式化输出,默认无换行) Base64
decode64 将Base64格式字符串解码为字节字符串 encoded: Base64 - 待解码的Base64字符串 Bytes
encodeUtf8 将普通字符串编码为UTF-8格式字符串 str: string - 待编码的普通字符串 Utf8
decodeUtf8 将UTF-8格式字符串解码为普通字符串 encoded: Utf8 - 待解码的UTF-8字符串 string
createBuffer 创建一个空的字节缓冲区对象 无参数 ByteBuffer
createBuffer 根据输入数据和编码格式创建字节缓冲区对象,支持多种输入格式 input: 用于初始化字节缓冲区的原始数据,支持字节字符串、数组缓冲区、缓冲区视图或字节字符串缓冲区格式 encoding: 可选,输入数据的编码格式,用于正确解析原始数据 ArrayBuffer

2.forge.util.binary

函数名 函数说明 参数说明 返回值类型
binary.raw.encode 将Uint8Array类型数据编码为字节字符串(Bytes) x: Uint8Array - 待编码的Uint8Array二进制数据 Bytes
binary.raw.decode 将字节字符串(Bytes)解码为Uint8Array,支持指定输出缓冲区和偏移量 1. str: Bytes - 待解码的字节字符串 2. output?: Uint8Array - 可选,输出缓冲区(复用内存) 3. offset?: number - 可选,输出缓冲区的写入偏移量 Uint8Array
binary.hex.encode 将二进制数据编码为十六进制字符串(Hex),支持多种输入格式 bytes: Bytes | ArrayBuffer | ArrayBufferView | ByteStringBuffer - 待编码的二进制数据 ArrayBuffer
binary.hex.decode 将十六进制字符串(Hex)解码为Uint8Array,支持指定输出缓冲区和偏移量 1. hex: Hex - 待解码的十六进制字符串 2. output?: Uint8Array - 可选,输出缓冲区(复用内存) 3. offset?: number - 可选,输出缓冲区的写入偏移量 Uint8Array
binary.base64.encode 将Uint8Array类型数据编码为Base64字符串,支持指定每行最大长度 1. input: Uint8Array - 待编码的Uint8Array二进制数据 2. maxline?: number - 可选,每行最大字符数(用于格式化输出,默认无换行) Base64
binary.base64.decode 将Base64字符串解码为Uint8Array,支持指定输出缓冲区和偏移量 1. input: Base64 - 待解码的Base64字符串 2. output?: Uint8Array - 可选,输出缓冲区(复用内存) 3. offset?: number - 可选,输出缓冲区的写入偏移量 Uint8Array

3.forge.util.text

函数名 所属命名空间 函数说明 参数说明 返回值类型
text.utf8.encode text.utf8 将普通字符串编码为UTF-8格式的Uint8Array二进制数据,支持指定输出缓冲区和偏移量 1. str: string - 待编码的普通字符串 2. output?: Uint8Array - 可选,输出缓冲区(复用内存,避免重复创建) 3. offset?: number - 可选,输出缓冲区的写入偏移量(从该位置开始写入编码后的数据) Uint8Array
ext.utf8.decode text.utf8 将UTF-8格式的Uint8Array二进制数据解码为UTF-8字符串 bytes: Uint8Array - 待解码的UTF-8格式二进制数据 Utf8
text.utf16.encode text.utf16 将普通字符串编码为UTF-16格式的Uint8Array二进制数据,支持指定输出缓冲区和偏移量 1. str: string - 待编码的普通字符串 2. output?: Uint8Array - 可选,输出缓冲区(复用内存,避免重复创建) 3. offset?: number - 可选,输出缓冲区的写入偏移量(从该位置开始写入编码后的数据) Uint8Array
text.utf16.decode text.utf16 将UTF-16格式的Uint8Array二进制数据解码为普通字符串 bytes: Uint8Array - 待解码的UTF-16格式二进制数据 string
相关推荐
小二·2 小时前
Python Web 开发进阶实战:生物启发计算 —— 在 Flask + Vue 中实现蚁群优化与人工免疫系统
前端·python·flask
2301_818732062 小时前
前端一直获取不到后端的值,和数据库字段设置有关 Oracle
前端·数据库·sql·oracle
vx_bisheyuange2 小时前
基于SpringBoot的酒店管理系统
前端·javascript·vue.js·spring boot·毕业设计
JaredYe2 小时前
node-plantuml-2:革命性的纯Node.js PlantUML渲染器,告别Java依赖!
java·开发语言·node.js·uml·plantuml·jre
慧一居士2 小时前
同一个服务器上不同的域名跳往不同的前端项目页面,不显示端口号 ngnix根据不同域名跳转
运维·服务器·前端
ct9782 小时前
WebGL核心API
前端·gis·webgl
lexiangqicheng2 小时前
Ant Design Pro 实战:Web 后台页面标准化开发规范与最佳实践
前端
ZI Keep Going2 小时前
前来填坑:Search Around the World全球联合部署搜索引擎
前端·javascript·搜索引擎
手握风云-2 小时前
JavaEE 进阶第十期:Spring MVC - Web开发的“交通枢纽”(四)
前端·spring·java-ee