# @fnando/keyring 中文文档

规范地址：https://npmcn.com/package/%40fnando/keyring/

版本：0\.4\.0
npm 元数据更新时间：2022-04-05T11:34:14.671Z
中文译文更新时间：2026-11-15T03:22:46.669Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40fnando/keyring
原文对照：https://npmcn.com/package/%40fnando/keyring/?lang=original
项目主页：https://github.com/fnando/keyring-node#readme
源码仓库：https://github.com/fnando/keyring-node

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：220 kB，17 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- 运行依赖：0 个
- 首次发布：2018-12-17T00:06:44.768Z
- 最新版本发布：2020-09-24T06:52:52.928Z
- 近 30 天下载量：6514（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：4（近 12 个月 0 个）

## 中文简介

带有密钥旋转的简单加密 。 包括后续支持.

## 安装

```sh
npm install @fnando/keyring
```

也可以使用：`pnpm add @fnando/keyring`、`yarn add @fnando/keyring`、`bun add @fnando/keyring`

## README

# 密钥环

简单加密并带有Node.js的密钥旋转支持.

![keyring: Simple encryption-at-rest with key rotation support for Node.js.](https://raw.githubusercontent.com/fnando/keyring-node/main/keyring.png)

[![Travis-CI](https://travis-ci.org/fnando/keyring-node.svg)](https://travis-ci.org/fnando/keyring-node)

注: **密钥环** 实值 _没有_ 用于加密密码,请使用 类似的东西 [微声](https://www.npmjs.com/package/bcrypt)它的本意为 在纯文本中加密您需要访问的敏感数据( 例如存储) 用户的OAuth令牌). 密码不属于这一类别.

此软件包完全独立于任何存储机制;目标是 提供几种易于与任何ORM相融合的功能. 与 但是,这个软件包会捆绑一个与 [排序](https://sequelizejs.com/)。 。 。 .

## 安装

在您的软件包中添加 `package.json` 使用雅恩语.

```console
yarn add -E @fnando/keyring
```

## 使用量

### 加密

默认情况下,AES-128-CBC是用于加密的算法. 此算法 使用 16 字节键,但需要使用比大小多一倍的键 因为其中一半的密钥将被用于生成 HMAC 。 前16个字节 将用作加密密钥,最后16个字节将用于 生成 HMAC.

使用随机数据库64-编码是推荐的方法. 很容易生成 使用下列命令键:

```console
$ dd if=/dev/urandom bs=32 count=1 2>/dev/null | openssl base64 -A
qUjOJFgZsZbTICsN0TMkKqUvSgObYxnkHDsazTqE5tM=
```

在 `value` 关键说明的章节 在键盘。 一半用于加密,一半用于HMAC.

#### 密钥大小

密钥大小取决于使用的算法. 键大小应该双倍 用于 HMAC 计算.

-   `aes-128-cbc`: 16字节(加密)+16字节(HMAC).
-   `aes-192-cbc`: 24字节(加密)+24字节(HMAC).
-   `aes-256-cbc`: 32 字节(加密)+ 32 字节(HMAC).

#### 关于加密信件

初始化矢量(IV)应当是不可预测的和独特的;理想的情况是: 将按密码随机排列。 它们不必是秘密的:IV是 通常只是添加到未加密的密码文本中。 可能听起来 矛盾的是,有些东西必须是不可预料和独特的,但并不 必须保密;必须记住攻击者必须不能 提前预测给定的IV是什么.

考虑到这一点, _密钥环_ 用途 `base64(hmac(unencrypted iv + encrypted message) + unencrypted iv + encrypted message)` 作为最后的信息。 如果你打算从其他加密中迁移出去 不使用 _密钥环_, (中文(简体) ), 确保你对此负责。 HMAC长32字节,IV长16字节 长.

### 密钥环

密钥是通过一个 keyring - a short JSON 文件来管理 加密密钥. 密钥环必须是 JSON 对象映射 键入键值。 密钥环必须至少有一把钥匙. 例如:

```json
{
  "1": "uDiMcWVNTuz//naQ88sOcN+E40CyBRGzGTT7OkoBS6M=",
  "2": "VN8UXRVMNbIh9FWEFVde0q7GUA1SGOie1+FgAKlNYHc="
}
```

这个 `id` 用于跟踪哪个密钥加密了哪个数据; 带有 更大的id被认为是更新的。 值为 加密密钥.

### 密钥旋转

与 **密钥环** 您可以同时拥有多个加密密钥和密钥旋转 相当直截了当:如果您在 _密钥环_ 具有较高编号 相对于任何其他密钥,当 对象或创建或更新。 不再使用的密钥可以是 安全离开 _密钥环_。 。 。 .

你一定要把钥匙环的ID保存下来 `encrypt()`· ; 否则,您可能无法解密值( 您总是可以解密值) 如果你仍然拥有 _全部_ 加密密钥).

如果你在用的话 **密钥环** 要加密数据库列,建议使用 分离 _密钥环_ 您计划加密的每个表格: 在您需要时(例如密钥泄漏),可以更容易地旋转密钥.

注意:这些例子上的密钥是硬编码的,但是你不应该用你的密码 基础。 你可以拿回来 _密钥环_ 从环境变量,如果你正在部署 改为 [赫鲁库](https://heroku.com/) 或部署一个JSON文件 配置管理软件(如Ansible,Pupet,Chef等).

### 键盘的基本使用

```js
import { keyring } from "@fnando/keyring";

const keys = { 1: "uDiMcWVNTuz//naQ88sOcN+E40CyBRGzGTT7OkoBS6M=" };
const encryptor = keyring(keys, { digestSalt: "<custom salt>" });

// STEP 1: Encrypt message using latest encryption key.
const [encrypted, keyringId, digest] = encryptor.encrypt("super secret");

console.log(`🔒 ${encrypted}`);
console.log(`🔑 ${keyringId}`);
console.log(`🔎 ${digest}`);
//=> 🔒 Vco48O95YC4jqj44MheY8zFO2NLMPp/KILiUGbKxHvAwLd2/AN+zUG650CJzogttqnF1cGMFb//Idg4+bXoRMQ==
//=> 🔑 1
//=> 🔎 e24fe0dea7f9abe8cbb192702578715079689a3e

// STEP 2: Decrypted message using encryption key defined by keyring id.
const decrypted = encryptor.decrypt(encrypted, keyringId);
console.log(`✉️ ${decrypted}`);
//=> ✉️ super secret
```

#### 更改加密算法

您可以在 `AES-128-CBC`, (中文(简体) ), `AES-192-CBC` 财务报告和审定财务报表 `AES-256-CBC`。通过 默认, `AES-128-CBC` 将被使用.

要指定加密算法,请设置 `encryption` 选项。 以下内容: 示例使用 `AES-256-CBC`。 。 。 .

```js
import { keyring } from "@fnando/keyring";

const keys = { 1: "uDiMcWVNTuz//naQ88sOcN+E40CyBRGzGTT7OkoBS6M=" };
const encryptor = keyring(keys, {
  encryption: "aes-256-cbc",
  digestSalt: "<custom salt>",
});
```

### 使用序列

如果你使用序列, 你可能不想手动处理 加密如上. 考虑到这一点, `keyring` 带有小插件的船舶 减轻手动处理属性加密/解密的所有痛苦,因为 还有钥匙旋转和消化.

首先,你必须装入一个设置模型的不同文件.

```js
const Sequelize = require("sequelize");
const sequelize = new Sequelize("postgres:///test", { logging: false });
const Keyring = require("@fnando/keyring/sequelize");

const User = await sequelize.define(
  "users",
  {
    id: {
      type: Sequelize.UUIDV4,
      primaryKey: true,
      allowNull: false,
      defaultValue: Sequelize.UUIDV4,
    },

    // This column is required and will store the
    // keyring id (which encryption key was used).
    keyring_id: Sequelize.INTEGER,

    // All encrypted columns must be prefixed with `encrypted_`.
    // Optionally, you may have a `<attribute>_digest` column,
    // will store a SHA1 digest from the value, making
    // unique indexing and searching easier.
    // Finally, notice that you're responsible for defining
    // a VIRTUAL property for all columns you're encrypting.
    encrypted_email: Sequelize.TEXT,
    email_digest: Sequelize.TEXT,
    email: Sequelize.VIRTUAL,
  },
  { timestamps: false },
);

// Retrieve encryption keys from `USER_KEYRING` environment variable.
// It's recommended that you use one keyring for each model, to make
// a rollout easier (e.g. an encryption key leaked).
//
// ```js
// const keys = JSON.parse(process.env.USER_KEYRING);
// ```
//
// Alternatively, you can load a JSON file deployed by some config management software like Ansible, Chef or Puppet.
//
// ```js
// const fs = require("fs");
// const keys = JSON.parse(fs.readFileSync("user_keyring.json"));
// ```
//
// For the purposes of this example, we're going to set keys manually.
// WARNING: DON'T EVER DO THAT FOR REAL APPS.
const keys = { 1: "uDiMcWVNTuz//naQ88sOcN+E40CyBRGzGTT7OkoBS6M=" };

// This is the step you set up your model with hooks to encrypt/decrypt
// columns. You can specify the encryption keys, which columns are going
// to be encrypted, how the column will be encrypted and the name of the
// keyring id column. You can see below the default values for `encryption`
// and keyring id column.
Keyring(User, {
  keys, // [required]
  columns: ["email"], // [required]
  digestSalt: "<custom salt>", // [required]
  keyringIdColumn: "keyring_id", // [optional]
  encryption: "aes-128-cbc", // [optional]
});

(async () => {
  // Now you can create records, like you usually do.
  const user = await User.create({ email: "john@example.com" });

  console.log(JSON.stringify(user, null, 2));

  // Let's update the email address.
  await user.update({ email: "john.doe@example.com" });

  console.log(JSON.stringify(user, null, 2));

  // Now let's pretend that you set USER_KEYRING env var to a
  // {1: old_key, 2: new_key} or rollout a new JSON file via your
  // config management software, and restarted the app.
  keys[2] = "VN8UXRVMNbIh9FWEFVde0q7GUA1SGOie1+FgAKlNYHc=";

  // To simply roll out a new encryption, just call `.save()`.
  // This will trigger a `beforeSave` hook, which will re-encrypt
  // all properties again.
  await user.save();

  console.log(JSON.stringify(user, null, 2));

  // Attributes are also re-encrypted when you call `.update()`.
  await user.update({ email: "john@example.com" });

  console.log(JSON.stringify(user, null, 2));
})();
```

#### 查询

加密的一个棘手方面是 查查已知的秘密记录 要解决 您可以为加密的字符串生成 SHA1 摘要 保存到数据库中.

`keyring` 检测是否存在 `<attribute>_digest` 列并更新 因此,SHA1摘要可用于独特的索引编制或 寻找。 你不必用散热盐,但很受推荐; 这样可以避免用户信息通过彩虹表被泄露.

```js
// A utility function to generate SHA1s out of strings.
const { sha1 } = require("@fnando/keyring");

await User.create({ email: "john@example.com" });

const user = await User.findOne({
  where: {
    email_digest: sha1("john@example.com", { digestSalt: "<custom salt>" }),
  },
});
```

### 与Ruby交换数据

如果你用鲁比,你可能会有兴趣 [https://github.com/fnando/atr keyring 互联网档案馆的存檔,存档日期2013-12-21](https://github.com/fnando/attr_keyring),它能够读写 使用相同的格式发送信件.

## 发展

检查后,运行 `yarn install` 以安装依赖。 接下来, 运行 `yarn test` 进行测试.

## 捐款

GitHub 上欢迎错误报告和拉取请求 [https://github.com/fnando/ keyring-node 互联网档案馆的存檔,存档日期2014-12-02](https://github.com/fnando/keyring-node)这个项目旨在成为一个安全, 欢迎合作空间,预计捐助方将遵守 页:1 [《促进者公约》](http://contributor-covenant.org/) 行为守则.

## 许可证

该宝石作为公开源码,按照以下规定提供: [MIT 许可证](https://opensource.org/licenses/MIT)。 。 。 .

## 图标

图标由 [图标geek26](https://www.flaticon.com/authors/icongeek26) 从 [平纹](https://www.flaticon.com/) 由创用CC授权使用.

## 行为守则

每个人都在互动 **密钥环** 项目的代码库, 问题跟踪器, 聊天室和邮件列表 [行为守则](https://github.com/fnando/keyring-node/blob/main/CODE_OF_CONDUCT.md)。 。 。 .

## 常见问题

### @fnando/keyring 是什么？

带有密钥旋转的简单加密 。 包括后续支持\.

### 如何安装 @fnando/keyring？

在项目目录运行 npm install @fnando/keyring，或使用 pnpm add / yarn add / bun add。

### @fnando/keyring 支持 TypeScript 吗？

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

### @fnando/keyring 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @fnando/keyring 可以商用吗？

@fnando/keyring 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @fnando/keyring 的下载量有多少？

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

### @fnando/keyring 还在维护吗？

最新版本 0\.4\.0 发布于 2020/09/24（6 年前）；至今共发布 4 个版本，其中过去 12 个月发布了 0 个；首次发布于 2018/12/17。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

