@arkstack/encryption

中文文档
0.22.2发布于 2026/11/07ES Module零依赖近 30 天下载 4128

Arkstack的Isomorphic端到端加密:AES-256-GCM密码,ECDH密钥对,和在节点和浏览器中运行相同的密钥生成/比较公用.

中文使用文档
文档目录16 节
  1. 目录
  2. 安装
  3. 盒子里的东西
  4. 对称加密
  5. 其他经认证的数据
  6. 字节
  7. 密钥
  8. 比较密钥
  9. 指纹
  10. 端到端加密
  11. 安全频道
  12. 密封盒
  13. 正在验证对话
  14. 同步节点 API
  15. 线条格式
  16. 运行时间要求

@arkstack/encryption

@arkstack/encryption

Arkstack 的零依赖异构加密 。 一个基于Web Crypto API的执行,在Node,Deno, Bun,浏览器和工人中运行不变,所以 在服务器上加密的浏览器解密, 在服务器上加密的浏览器解密。 。 。 .

目录

安装

pnpm add @arkstack/encryption

Arkstack 应用程序已经通过 @arkstack/common 再出口情况 Encryption。 。 。 .

盒子里的东西

导出它会做什么
CipherAES-256-GCM 对称加密
EncryptionKey对称的密钥值:生成、出自、指纹、比较
Keys密钥生成和恒定时间比较助手
KeyPairECDH P-256 身份,可序列至基数64url
SecureChannel两个身份之间共享的密钥和上面的信息
SealedBox匿名加密公钥
Codecbase64url / hex / utf8 转换和恒定时间比较
NodeCipher节点同步 AES-256-GCM(@arkstack/encryption/node(中文(简体) )

对称加密

import { Cipher, Keys } from '@arkstack/encryption'

const key = Keys.generate()

const payload = await Cipher.encrypt('my-secret-value', key)
// "abc123:def456:ghi789"

await Cipher.decrypt(payload, key)
// "my-secret-value"

密码实例导入密钥一次, 当加密许多值时值得这样做 :

const cipher = await Cipher.from(process.env.APP_KEY!)

const rows = await Promise.all(values.map((value) => cipher.encrypt(value)))

任何关键代表工作: EncryptionKey粗线 Uint8Array 字节, a CryptoKey,一个完全32字节的基质64url字符串,或任何其他字符串,用SHA-256来散开并当作密码句处理.

其他经认证的数据

aad 未加密,但它与密码文本相接:除非提供相同值,否则解密失败。 用它来将一个有效载荷固定在它所属的上下文上,所以一个有效的密码文本不能在其他地方重放.

const payload = await cipher.encrypt(body, { aad: `conversation:${id}` })

await cipher.decrypt(payload, { aad: `conversation:${id}` }) // ok
await cipher.decrypt(payload, { aad: 'conversation:other' }) // throws

字节

encryptBytes 编号 : decryptBytes 带回 Uint8Array 二进制有效载荷.

密钥

import { Keys } from '@arkstack/encryption'

Keys.generate() // EncryptionKey, 32 random bytes
Keys.generateString() // the same, base64url encoded for storage
Keys.token(16) // a random URL-safe token (not a key)

密码被拉伸,秘密被散开:

const { key, salt, iterations } = await Keys.derive(password) // PBKDF2-HMAC-SHA256
const same = await Keys.derive(password, { salt, iterations })

await Keys.fromSecret(process.env.APP_KEY!) // SHA-256, matching Arkstack's app key handling

比较密钥

这里的每个比较都会在恒定的时间运行, 并且从不丢入错误的输入—— 它返回 false。 。 。 .

Keys.compare(left, right) // two keys already in key form
await Keys.matches(passphrase, key) // resolves both sides first
await Keys.samePublicKey(left, right) // two identities

指纹

指纹是钥匙的文摘,可以安全显示或日志. 两个人读取相同的指纹 拿着相同的钥匙.

await Keys.fingerprint(key)
// "3f8a1c02 9b4e7d15 c6a0ff31 2e5b8d94"

端到端加密

一种身份是ECDH P-256键对. 公开的半个出版,私人的半个不离开主人.

import { Keys } from '@arkstack/encryption'

const identity = await Keys.generateSerializedPair()
// { publicKey: 'MFkwEwYH…', privateKey: 'MIGHAgEA…' }

两者都为base64url DER,因此在JSON,信头,查询字符串和数据库列不变的情况下幸存了下来,并在其他运行时间被干净地导入.

安全频道

每方将自己的私钥与对方的公钥结合. 两者都到达了相同的AES-256-GCM密钥而从未穿过过电线——服务器可以在无法读取的情况下去路由密码文本.

import { SecureChannel } from '@arkstack/encryption'

// In the browser, as Alice
const outbound = await SecureChannel.between(alice.privateKey, bobPublicKey)
const message = await outbound.encrypt('hey bob')

// On Bob's device
const inbound = await SecureChannel.between(bob.privateKey, alicePublicKey)
await inbound.decrypt(message) // "hey bob"

过 info 从同一对身份中获取用于不同目的的单独密钥:

const chat = await SecureChannel.between(alice.privateKey, bobPublicKey, {
  info: `chat:${id}`,
})
const files = await SecureChannel.between(alice.privateKey, bobPublicKey, {
  info: `files:${id}`,
})

密封盒

加密到没有自己身份的公钥 。 每条消息都会生成一对被丢弃的密钥,其公用半部在有效载荷中出行;只有接收者的私人密钥才能打开结果——发送者之后无法解密自己的消息.

import { SealedBox } from '@arkstack/encryption'

const payload = await SealedBox.seal('anonymous tip', recipientPublicKey)

await SealedBox.open(payload, recipientPrivateKey) // "anonymous tip"

正在验证对话

密钥协议可以防止偷听者,而不是防止服务器将错误的公钥相接. 一个安全号码让参与者可以排除他们已经信任的任何频道.

const number = await Keys.safetyNumber(alicePublicKey, bobPublicKey)
// "48213 90277 11408 63925 …"

await Keys.confirmSafetyNumber(alicePublicKey, bobPublicKey, scanned)

无论由谁发起,双方的值都是相同的,确认时会忽略白空. channel.safetyNumber() 返回打开的频道的相同字符串.

同步节点 API

Web Crypto API是各地同步的. 当服务器上真的需要同步呼叫时, @arkstack/encryption/node 提供一种发射字节相同的有效载荷:

import { NodeCipher } from '@arkstack/encryption/node'

const payload = NodeCipher.encrypt('value', NodeCipher.fromSecret(process.env.APP_KEY!))

NodeCipher.decrypt(payload, NodeCipher.fromSecret(process.env.APP_KEY!))

它住在自己的入口后 所以浏览器捆绑永远不会拉进来 node:crypto。 。 。 .

NodeCipher.resolve() 将一个完全32字节的基质64url字符串作为原始密钥材料,其他东西作为密码句,镜像 EncryptionKey.resolve()当一个秘密必须永远被散开时——如 APP_KEY 已经--使用 NodeCipher.fromSecret()。 。 。 .

线条格式

两个密码读取和写出相同的有效载荷:

仁爱格式
密码<iv>:<authTag>:<ciphertext>
密封盒ark1:<ephemeralPublicKey>:<iv>:<authTag>:<ciphertext>

每段都是未加入基数64url. IV为12字节,GCM标记为16字节.

运行时间要求

网络加密执行 globalThis.crypto数字 :

  • 节点 19+,或节点18与 globalThis.crypto 可用.
  • 浏览器 在安全的情况下https 或者说 localhost) (中文(简体) ).
  • 德诺, (中文(简体) ), 阿宝和Cloudflare/德诺风格的工人 走出盒子.

同步 /node 入口需要节点.

版本与发布记录

@arkstack/encryption 共发布 28 个版本,首次发布于 2026/08/27;过去 12 个月发布了 28 个版本。

版本发布日期距今
0.22.2latest2026/11/07今天
0.22.12026/11/052 天前
0.22.02026/11/052 天前
0.21.12026/11/052 天前
0.21.02026/10/2810 天前
0.20.22026/10/2315 天前

关于 @arkstack/encryption 的常见问题

@arkstack/encryption 是什么?

Arkstack的Isomorphic端到端加密:AES-256-GCM密码,ECDH密钥对,和在节点和浏览器中运行相同的密钥生成/比较公用.

如何安装 @arkstack/encryption?

在项目目录运行 npm install @arkstack/encryption,或使用 pnpm add / yarn add / bun add。

@arkstack/encryption 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/arkstack__encryption 是否存在。

@arkstack/encryption 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@arkstack/encryption 可以商用吗?

@arkstack/encryption 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@arkstack/encryption 的下载量有多少?

根据 npm 官方下载统计,@arkstack/encryption 在 2026/10/07 – 2026/11/05 这 30 天内被下载 4,128 次,日均约 138 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arkstack/encryption 还在维护吗?

最新版本 0.22.2 发布于 2026/11/07(今天);至今共发布 28 个版本,其中过去 12 个月发布了 28 个;首次发布于 2026/08/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。