NIP-17: 私信安全指南
了解 NIP-17,NIP-04 的安全替代品,以及如何在 Nostr 中迁移你的私人消息
NIP-17 代表了 Nostr 私信工作方式的重大安全升级。本指南解释为什么你应该关注这个协议改进,如何从旧的 NIP-04 标准迁移,以及如何保护你的通信安全。
什么是 NIP-17?
NIP-17 是一个 Nostr 协议规范,定义了使用称为 “seal + gift wrap” 的双层加密系统的私人直接消息。它是为了解决之前 NIP-04 加密方法的基本安全缺陷而创建的。
与使用单层 AES-256-CBC 加密的 NIP-04 不同,NIP-17 使用:
- Seal(kind 13)—— 内层,加密消息内容,并隐藏是哪个密钥签的名
- Gift Wrap(kind 1059)—— 外层信封,由一个用完即弃的一次性密钥签名,因此你的真实身份绝不会出现在中继所存储的那个事件上
这种分层意味着:
- 消息内容保持私密
- 中继看不出消息是谁发的 —— gift wrap 是由随机的一次性密钥签名的,而不是由你签名
- 时间戳经过随机化处理,消息的发送时机更难被关联分析
中继仍然看得到你在跟谁发消息
Gift wrap 会在一个明文 p 标签里携带接收者的公钥。它必须这么做——否则接收者的
中继根本不知道该把消息投递给谁。NIP-17 隐藏的是发送者,而不是接收者。
任何能读取中继事件流的人,都能看到有人在什么时间给你发了消息,只是不知道发的人是谁、发了什么。如果你的威胁模型要求连”你收到过消息”这件事本身都必须隐藏,那么仅靠 NIP-17 是不够的。
为什么 NIP-17 重要:NIP-04 安全问题
NIP-04 是 Nostr 的原始私信协议,但它有几个关键的安全问题,使其不适合真正私密的通信。
比较:NIP-04 vs NIP-17
| 功能 | NIP-04 | NIP-17 |
|---|---|---|
| 加密 | 单层 AES-256-CBC | 双层(seal + gift wrap) |
| 发送者元数据 | 对中继可见 | 对除接收者外的所有人隐藏 |
| 接收者元数据 | 对中继可见 | 对除接收者外的所有人隐藏 |
| 消息内容 | 加密 | 加密 |
| 重放保护 | 无 | 内置时间戳 |
| 前向保密 | 否 | 更好(每条消息使用不同密钥) |
| 安全状态 | 已弃用 | 推荐 |
| 互操作性 | 广泛支持 | 支持度正在增长 |
NIP-04 的核心问题
NIP-04 消息把谁在跟谁说话暴露给每一个存储它们的中继。(Nostr 没有区块链——事件只是存放在中继上,任何人都可以从中继读取。)虽然消息正文是加密的,但信封包含:
# NIP-04 事件结构(简化)
{
"pubkey": "<sender_public_key>", # 任何人都能看到谁发送的
"tags": [["p", "<recipient_pubkey>"]], # 任何人都能看到谁接收的
"content": "<encrypted_content>" # 只有内容是隐藏的
}
这意味着中继运营商、网络观察者和数据抓取者可以:
- 构建社交图谱,显示谁与谁通信
- 跟踪通信模式和频率
- 从消息时间推断关系
NIP-17 通过将整个消息结构包装在额外的加密层中来解决这个问题,使得没有解密密钥就无法看到发送者或接收者信息。
NIP-17 如何工作:Seal + Gift Wrap
了解技术实现有助于理解安全改进。
Gift Wrap 层(外层)
Gift wrap 是隐藏所有元数据的外层信封。它使用从接收者公钥派生的特殊 “gift wrap 密钥” 进行加密。这一层包含:
- 一个随机公钥(与真实发送者无关)
- 接收者的公钥
- 时间戳
- 密封的内层消息
Seal 层(内层)
Seal 位于 gift wrap 内部,包含实际消息。这一层:
- 使用新鲜的临时密钥对加密
- 包含发送者的真实公钥
- 包括消息内容
- 有自己的时间戳用于重放保护
Gift Wrap(外层)
随机公钥、接收者提示——中继能看到的就只有这些
Seal(内层)
使用临时密钥加密
实际消息内容
发送者:真实公钥 · 时间戳:1234567890
主要优势
- 元数据隐私:除了接收者,没人能确定谁发送了消息或发送给谁
- 不可链接性:同一方之间的多条消息对观察者显示为不相关的事件
- 更好的前向保密:每条消息使用唯一的临时密钥
投递:私信中继列表(kind 10050)
Seal 和 gift wrap 描述的是消息如何打包。还有第三个部分——kind 10050 事件——描述消息投递到哪里。它是一份小型的、公开的中继列表,列出接收你私信的中继。
规范在这一点上非常严格:发送方必须只把 gift wrap 发布到接收者 kind 10050 列表中的中继。如果你从未发布过这样一份列表,规范就把你视为”尚未准备好接收消息”,客户端甚至不应该尝试投递——因此发给你的私信会被静默丢弃,永远无法送达。两边都不会有任何报错。
两条实用规则:
- 在期待收到任何 NIP-17 私信之前,先发布一份(见下方迁移指南的第 3 步)
- 保持列表精简——规范建议 1-3 个中继,而且你列出的每一个中继都能看到谁在给你发消息
迁移指南:从 NIP-04 切换到 NIP-17
使用现代 Nostr 客户端迁移到 NIP-17 很简单。以下是切换方法。
第 1 步:检查你的客户端支持
在迁移之前,验证你的客户端支持 NIP-17:
| 客户端 | NIP-17 支持 | 状态 |
|---|---|---|
| Damus | 是 | 新私信默认使用 |
| Amethyst | 是 | 新私信默认使用 |
| Primal | 是 | 支持 |
| Coracle | 是 | 支持 |
| Iris | 是 | 支持 |
| Snort | 是 | 支持 |
| Nos | 是 | 支持 |
第 2 步:在客户端中启用 NIP-17
Damus (iOS/macOS)
- 打开设置 → 隐私与安全
- 滚动到 “消息加密”
- 将 “对新消息使用 NIP-17” 切换为开启
- 你的新私信将自动使用 NIP-17
注意:旧的 NIP-04 消息仍然可读,但新消息使用 NIP-17。
Amethyst (Android)
- 进入设置 → 消息
- 启用 “对私信使用 NIP-17”
- 重启应用以获得完整效果
Primal (iOS/Android/Web)
- 导航到设置 → 隐私
- 在 “私信” 下,选择 “NIP-17(推荐)”
- 更改立即应用于新对话
第 3 步:发布你的私信中继列表(kind 10050)
NIP-17 的发送方只会投递到你在 kind 10050 事件中列出的中继——没有它,发给你的消息会被静默丢弃(见上方 投递:私信中继列表)。
- 在你的客户端中,寻找私信、私人消息或消息中继设置
- 添加一到三个接收 gift wrap(kind 1059)的中继——有些中继会拒绝它们
- 保存——你的客户端会为你发布 kind 10050 列表
有些客户端在你启用 NIP-17 时会自动发布这份列表。但不要想当然:在依赖它之前,先在第 5 步验证消息能够送达。
第 4 步:与你的联系人沟通
NIP-17 只有在双方都支持 NIP-17 时才有效。向经常联系的人发送一条消息:
nostr:note1... # 迁移消息模板
"嘿!我正在升级到 NIP-17 以获得更好的私信隐私。
如果你还没有更新你的 Nostr 客户端,请更新。
我们未来的消息将更加安全!"
第 5 步:验证迁移成功
要确认 NIP-17 正在工作:
- 向自己或朋友发送一条测试消息
- 检查事件 kind(应该是
1059表示 gift wraps) - 在消息详情中查找
kind: 1059 p标签应该指向一个随机临时密钥,而不是你朋友的真实密钥
// NIP-17 事件示例(简化)
{
"kind": 1059, // Gift wrap 事件
"pubkey": "<random_ephemeral_key>", // 不是真实发送者!
"tags": [["p", "<recipient_pubkey>"]],
"content": "<encrypted_seal_content>"
}
客户端特定设置指南
Damus
Damus 在最近的版本中使 NIP-17 成为新私信默认。如果你使用的是旧版本:
- 从 App Store 更新到最新的 Damus
- NIP-17 自动为新对话启用
- 检查消息详情(长按)以查看 “NIP-17” 徽章
专业提示:Damus 在安全消息上显示带有 “NIP-17” 文本的锁定图标。
Amethyst
Amethyst 支持 NIP-17,但可能需要显式启用:
- 设置 → 高级 → 协议设置
- 启用 “NIP-17 gift wrap for DMs”
- 客户端将自动与支持 NIP-17 的联系人协商
注意:如果接收者不支持 NIP-17,Amethyst 会优雅地回退到 NIP-04。
Primal
Primal 具有出色的 NIP-17 支持:
- 设置 → 安全与隐私
- 在 “消息协议” 下选择 “NIP-17(私有)”
- 可选:启用 “自动升级 NIP-04 对话” 以转换现有聊天
安全最佳实践
在使用 NIP-17 时最大化你的隐私:
1. 在敏感通信前验证客户端支持
在分享敏感信息之前,始终确认你的联系人使用支持 NIP-17 的客户端。向仅支持 NIP-04 的客户端发送 NIP-17 将导致无法阅读的消息。
2. 不要在同一线程中混合协议
通过每个对话只使用一种协议来避免混淆。如果你从 NIP-04 开始,就用 NIP-04 结束,或者在切换时明确指示。
3. 为高安全性对话使用新密钥
为了最大安全性:
- 为敏感通信创建专用密钥对
- 通过安全的外部渠道分享公钥
- 定期轮换密钥
4. 注意其他事件类型中的元数据
NIP-17 只保护私信。其他事件类型(笔记、反应、关注)仍然暴露社交图谱数据。使用多个身份进行隔离。
5. 选择注重隐私的中继
即使使用 NIP-17,你的流量模式对中继也是可见的。使用:
- Tor 或 VPN 获得额外的网络级隐私
- 不记录或保留消息元数据的中继
- 多个中继来分散你的流量
6. 了解局限性
NIP-17 提供出色的隐私,但并不完美:
- 中继仍然可以看到 IP 地址(使用 VPN/Tor)
- 时间分析可以揭示通信模式
- 受损的客户端可能泄露信息
- 接收者始终看到发送者身份
常见问题故障排除
「我的消息从未送达」——先检查你的私信中继列表
这是 NIP-17 最常见的故障,而且几乎从来不是加密问题。
NIP-17 的发送方不会投递到你平常使用的中继。他们会寻找一个 kind 10050 事件 ——即你公开发布的、接收私信的中继列表——并且只把 gift wrap 发送到那里。如果你 从未发布过这样一份列表,发送方的客户端就无处投递,消息会被静默丢弃。两边的界面 都不会有任何提示。
修复方法: 在一个支持 NIP-17 的客户端里,找到私信中继设置并至少保存一个中继, 这会发布你的 kind 10050 列表。请选择真正接收 gift wrap 的中继——有些中继会直接 拒绝 kind 1059。 (这就是迁移指南的第 3 步——如果你跳过了它,请从那里开始。)
列表要短。你列出的每一个中继,都是一个能看到谁在给你发消息的中继。
“消息显示为不可读或乱码”
原因:接收者不支持 NIP-17 解决方案:要求接收者更新他们的客户端,或暂时切换回 NIP-04
”看不到某人是否已读我的 NIP-17 消息”
原因:NIP-17 的已读回执尚未标准化 解决方案:这是预期行为。NIP-17 优先考虑隐私而非送达确认。
“消息顺序错乱”
原因:设备之间的时钟偏差 解决方案:确保你的设备时间已同步(启用自动时间同步)
“中继拒绝 NIP-17 事件”
原因:中继软件过旧 解决方案:
- 检查中继支持的 NIP
- 添加支持 NIP-17 的现代中继
- 向中继运营商报告
”客户端同时显示 NIP-04 和 NIP-17 选项”
预期行为:许多客户端在过渡期间支持两者。只要可用,始终选择 NIP-17。
Nostr 私信的未来
NIP-17 是 Nostr 私信的当前黄金标准,但开发仍在继续:
- NIP-44:可能取代 NIP-17 的改进加密方案
- 群组加密:正在开发私人群组消息协议
- 支付集成:带有闪电网络支付的私信
通过以下方式保持更新:
- nostr:npub1… # Nostr 协议开发
- nostr:npub1… # 安全最佳实践
结论
NIP-17 代表了 Nostr 隐私的重大进步。通过解决 NIP-04 的元数据泄露问题,它实现了真正保护内容和通信模式的私人直接消息。
迁移过程很简单:更新你的客户端,验证你的联系人支持 NIP-17,享受增强的隐私。随着广泛客户端支持已经可用,没有理由继续使用已弃用的 NIP-04 协议。
行动项目:
- ✅ 将你的 Nostr 客户端更新到最新版本
- ✅ 在设置中启用 NIP-17
- ✅ 发布你的私信中继列表(kind 10050)——没有它,什么都收不到
- ✅ 与联系人确认他们支持 NIP-17
- ✅ 对所有新的私人对话使用 NIP-17
记住:隐私是一种实践,而不是产品。NIP-17 给了你工具——明智地使用它们。
测试你的 NIP-17 知识
准备好检查你对安全消息的理解了吗?
NIP-17 改进
0/5 已回答
最后更新:2026年7月28日
有问题?在 Nostr 上加入讨论或在此文档仓库中提出问题。
继续阅读
发现错别字或不清楚的地方?在 GitHub 上编辑此指南。