NIP-17:Nostr私密直接消息方案
NIP-17 定义了 Nostr 协议中基于 NIP-44 加密和 NIP-59 密封/礼物包装的私密直接消息方案。
私有直连消息
draft optional relay
本 NIP 定义了一种加密聊天方案,该方案使用 NIP-44 加密和 NIP-59 的密封与礼物包装。
任何发送到加密聊天的事件都不得签名,并且必须按照 NIP-59 中描述的方式加密,如下所示。省略签名可以使消息在意外或恶意泄露时具有可否认性,同时仍允许接收者进行身份验证。
按照惯例,kind 14 直连消息、kind 15 文件消息和 kind 7 反应 可以发送到加密聊天。
Kind 定义
聊天消息
Kind 14 是聊天消息。p 标签标识一个或多个消息接收者。
{
"id": "<usual hash>",
"pubkey": "<sender-pubkey>",
"created_at": "<current-time>",
"kind": 14,
"tags": [
["p", "<receiver-1-pubkey>", "<relay-url>"],
["p", "<receiver-2-pubkey>", "<relay-url>"],
["e", "<kind-14-id>", "<relay-url>"] // 如果这是回复
["subject", "<conversation-title>"],
// 其余标签...
],
"content": "<message-in-plain-text>",
}
.content 必须是纯文本。字段 id 和 created_at 是必需的。
e 标签表示此帖子回复的直接父消息。
当在 .content 中使用 NIP-21 引用事件时,可以使用 q 标签。
["q", "<event-id> or <event-address>", "<relay-url>", "<pubkey-if-a-regular-event>"]
文件消息
{
"id": "<usual hash>",
"pubkey": "<sender-pubkey>",
"created_at": "<current-time>",
"kind": 15,
"tags": [
["p", "<receiver-1-pubkey>", "<relay-url>"],
["p", "<receiver-2-pubkey>", "<relay-url>"],
["e", "<kind-14-id>", "<relay-url>", "reply"], // 如果这是回复
["subject", "<conversation-title>"],
["file-type", "<file-mime-type>"],
["encryption-algorithm", "<encryption-algorithm>"],
["decryption-key", "<decryption-key>"],
["decryption-nonce", "<decryption-nonce>"],
["x", "<the SHA-256 hexencoded string of the file>"],
// 其余标签...
],
"content": "<file-url>"
}
Kind 15 用于发送加密文件事件消息:
file-type: 指定加密前附件文件的 MIME 类型(例如image/jpeg、audio/mpeg等)。encryption-algorithm: 指示用于加密文件的加密算法。支持的算法:aes-gcm。decryption-key: 接收者用于解密文件的解密密钥。decryption-nonce: 接收者用于解密文件的解密 nonce。content: 文件的 URL(<file-url>)。x包含加密文件的 SHA-256 十六进制编码字符串。ox包含加密前文件的 SHA-256 十六进制编码字符串。size(可选) 加密文件的大小(字节数)dim(可选) 像素尺寸,形式为<width>x<height>thumbhash(可选) 客户端加载文件时显示的 thumbhashblurhash(可选) 客户端加载文件时显示的 blurhashthumb(可选) 具有相同宽高比的缩略图 URL(使用相同的密钥和 nonce 加密)fallback(可选) 当url失败时的零个或多个备用文件源(使用相同的密钥和 nonce 加密)
聊天室
pubkey + p 标签的集合定义了一个聊天室。如果添加了新的 p 标签或移除了现有的 p 标签,则会创建一个新的房间,并拥有干净的消息历史。
客户端应该将同一房间的消息渲染为连续线程。
可选的 subject 标签定义了对话的当前名称/主题。任何成员都可以通过向现有的 pubkey + p 标签房间提交一个新的 subject 来更改主题。不需要在每条消息中都发送 subject。聊天室中最新的 subject 就是对话的主题。
加密
按照 NIP-59 的要求,未签名的聊天消息必须被密封(kind:13),然后向每个接收者和发送者单独进行礼物包装(kind:1059)。
{
"id": "<usual hash>",
"pubkey": randomPublicKey,
"created_at": randomTimeUpTo2DaysInThePast(),
"kind": 1059, // 礼物包装
"tags": [
["p", receiverPublicKey, "<relay-url>"] // 接收者
],
"content": nip44Encrypt(
{
"id": "<usual hash>",
"pubkey": senderPublicKey,
"created_at": randomTimeUpTo2DaysInThePast(),
"kind": 13, // 密封
"tags": [], // 无标签
"content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey),
"sig": "<signed by senderPrivateKey>"
},
randomPrivateKey, receiverPublicKey
),
"sig": "<signed by randomPrivateKey>"
}
加密算法必须使用最新版本的 NIP-44。
客户端必须验证 kind:13 的 pubkey 是否与 kind:14 上的 pubkey 相同,否则任何发送者都可以通过简单地更改 kind:14 上的 pubkey 来冒充他人。
客户端应该在密封和礼物包装中将 created_at 随机设置为过去两天内的某个时间点,以确保按 created_at 分组不会泄露任何元数据。
礼物包装的 p 标签可以是接收者的主 pubkey,也可以是为接收 DM 而创建的别名密钥,从而避免暴露接收者的身份。
客户端可以通过在每个接收者的礼物包装中设置 expiration 标签,或者不为发送者的公钥生成礼物包装,来提供消失消息。该标签也应该包含在 kind 13 密封中,以防泄露。
发布
Kind 10050 表示用户接收 DM 的首选中继。该事件必须包含一个带有中继 URI 的 relay 标签列表。
{
"kind": 10050,
"tags": [
["relay", "wss://inbox.nostr.wine"],
["relay", "wss://myrelay.nostr1.com"],
],
"content": "",
// 其他字段...
}
客户端应该将包含密封谣言的礼物包装后的 kind 1059 事件发布到接收者的 kind 10050 事件中列出的中继。如果找不到该事件,则表明用户尚未准备好接收此 NIP 下的消息,客户端不应尝试。
中继
中继可以通过仅向事件中 p 标签标记的用户提供 kind:1059 事件(使用 NIP 42 AUTH 强制执行)来保护消息元数据。
客户端应该引导用户将 kind:10050 列表保持在较小规模(1-3 个中继),并且应该将它们分散到尽可能多的可行中继上。
优势与限制
本 NIP 提供以下隐私和安全特性:
- 无元数据泄露:参与者身份、每条消息的真实日期和时间、事件种类及其他事件标签都向公众隐藏。仅凭公开信息无法将发送者和接收者联系起来。
- 无公开群组标识符:没有公共的中心队列、频道或其他收敛标识符来关联或统计同一群组中的所有消息。
- 无审核:没有群组管理员:没有邀请或封禁。
- 无共享秘密:没有必须为所有成员所知的秘密,这些秘密可能泄露或被错误分享。
- 完全可恢复:任何拥有用户私钥的客户端都可以完全恢复消息。
- 可选的前向保密:用户和客户端可以选择加入“消失消息”。
- 使用公共中继:消息可以在不损失隐私的情况下通过公共中继流动。私有中继可以进一步增强隐私,但并非必需。
- 冷存储:用户可以单方面选择将其消息与一个专门用于 DM 备份和恢复的单独密钥进行共享。
这种方法的主要限制是必须向每个接收者发送一个单独的加密事件。超过 100 名参与者的群聊应寻找更合适的消息传递方案。
示例
此示例将消息 Hola, que tal? 从 nsec1w8udu59ydjvedgs3yv5qccshcj8k05fh3l60k9x57asjrqdpa00qkmr89m 发送到 nsec12ywtkplvyq5t6twdqwwygavp5lm4fhuang89c943nf2z92eez43szvn4dt。
两个最终的 GiftWrap,分别发送给接收者和发送者,如下所示:
{
"id":"2886780f7349afc1344047524540ee716f7bdc1b64191699855662330bf235d8",
"pubkey":"8f8a7ec43b77d25799281207e1a47f7a654755055788f7482653f9c9661c6d51",
"created_at":1703128320,
"kind":1059,
"tags":[
["p", "918e2da906df4ccd12c8ac672d8335add131a4cf9d27ce42b3bb3625755f0788"]
],
"content":"AsqzdlMsG304G8h08bE67dhAR1gFTzTckUUyuvndZ8LrGCvwI4pgC3d6hyAK0Wo9gtkLqSr2rT2RyHlE5wRqbCOlQ8WvJEKwqwIJwT5PO3l2RxvGCHDbd1b1o40ZgIVwwLCfOWJ86I5upXe8K5AgpxYTOM1BD+SbgI5jOMA8tgpRoitJedVSvBZsmwAxXM7o7sbOON4MXHzOqOZpALpS2zgBDXSAaYAsTdEM4qqFeik+zTk3+L6NYuftGidqVluicwSGS2viYWr5OiJ1zrj1ERhYSGLpQnPKrqDaDi7R1KrHGFGyLgkJveY/45y0rv9aVIw9IWF11u53cf2CP7akACel2WvZdl1htEwFu/v9cFXD06fNVZjfx3OssKM/uHPE9XvZttQboAvP5UoK6lv9o3d+0GM4/3zP+yO3C0NExz1ZgFmbGFz703YJzM+zpKCOXaZyzPjADXp8qBBeVc5lmJqiCL4solZpxA1865yPigPAZcc9acSUlg23J1dptFK4n3Tl5HfSHP+oZ/QS/SHWbVFCtq7ZMQSRxLgEitfglTNz9P1CnpMwmW/Y4Gm5zdkv0JrdUVrn2UO9ARdHlPsW5ARgDmzaxnJypkfoHXNfxGGXWRk0sKLbz/ipnaQP/eFJv/ibNuSfqL6E4BnN/tHJSHYEaTQ/PdrA2i9laG3vJti3kAl5Ih87ct0w/tzYfp4SRPhEF1zzue9G/16eJEMzwmhQ5Ec7jJVcVGa4RltqnuF8unUu3iSRTQ+/MNNUkK6Mk+YuaJJs6Fjw6tRHuWi57SdKKv7GGkr0zlBUU2Dyo1MwpAqzsCcCTeQSv+8qt4wLf4uhU9Br7F/L0ZY9bFgh6iLDCdB+4iABXyZwT7Ufn762195hrSHcU4Okt0Zns9EeiBOFxnmpXEslYkYBpXw70GmymQfJlFOfoEp93QKCMS2DAEVeI51dJV1e+6t3pCSsQN69Vg6jUCsm1TMxSs2VX4BRbq562+VffchvW2BB4gMjsvHVUSRl8i5/ZSDlfzSPXcSGALLHBRzy+gn0oXXJ/447VHYZJDL3Ig8+QW5oFMgnWYhuwI5QSLEyflUrfSz+Pdwn/5eyjybXKJftePBD9Q+8NQ8zulU5sqvsMeIx/bBUx0fmOXsS3vjqCXW5IjkmSUV7q54GewZqTQBlcx+90xh/LSUxXex7UwZwRnifvyCbZ+zwNTHNb12chYeNjMV7kAIr3cGQv8vlOMM8ajyaZ5KVy7HpSXQjz4PGT2/nXbL5jKt8Lx0erGXsSsazkdoYDG3U",
"sig":"a3c6ce632b145c0869423c1afaff4a6d764a9b64dedaf15f170b944ead67227518a72e455567ca1c2a0d187832cecbde7ed478395ec4c95dd3e71749ed66c480"
}
{
"id":"162b0611a1911cfcb30f8a5502792b346e535a45658b3a31ae5c178465509721",
"pubkey":"626be2af274b29ea4816ad672ee452b7cf96bbb4836815a55699ae402183f512",
"created_at":1702711587,
"kind":1059,
"tags":[
["p", "44900586091b284416a0c001f677f9c49f7639a55c3f1e2ec130a8e1a7998e1b"]
],
"content":"AsTClTzr0gzXXji7uye5UB6LYrx3HDjWGdkNaBS6BAX9CpHa+Vvtt5oI2xJrmWLen+Fo2NBOFazvl285Gb3HSM82gVycrzx1HUAaQDUG6HI7XBEGqBhQMUNwNMiN2dnilBMFC3Yc8ehCJT/gkbiNKOpwd2rFibMFRMDKai2mq2lBtPJF18oszKOjA+XlOJV8JRbmcAanTbEK5nA/GnG3eGUiUzhiYBoHomj3vztYYxc0QYHOx0WxiHY8dsC6jPsXC7f6k4P+Hv5ZiyTfzvjkSJOckel1lZuE5SfeZ0nduqTlxREGeBJ8amOykgEIKdH2VZBZB+qtOMc7ez9dz4wffGwBDA7912NFS2dPBr6txHNxBUkDZKFbuD5wijvonZDvfWq43tZspO4NutSokZB99uEiRH8NAUdGTiNb25m9JcDhVfdmABqTg5fIwwTwlem5aXIy8b66lmqqz2LBzJtnJDu36bDwkILph3kmvaKPD8qJXmPQ4yGpxIbYSTCohgt2/I0TKJNmqNvSN+IVoUuC7ZOfUV9lOV8Ri0AMfSr2YsdZ9ofV5o82ClZWlWiSWZwy6ypa7CuT1PEGHzywB4CZ5ucpO60Z7hnBQxHLiAQIO/QhiBp1rmrdQZFN6PUEjFDloykoeHe345Yqy9Ke95HIKUCS9yJurD+nZjjgOxZjoFCsB1hQAwINTIS3FbYOibZnQwv8PXvcSOqVZxC9U0+WuagK7IwxzhGZY3vLRrX01oujiRrevB4xbW7Oxi/Agp7CQGlJXCgmRE8Rhm+Vj2s+wc/4VLNZRHDcwtfejogjrjdi8p6nfUyqoQRRPARzRGUnnCbh+LqhigT6gQf3sVilnydMRScEc0/YYNLWnaw9nbyBa7wFBAiGbJwO40k39wj+xT6HTSbSUgFZzopxroO3f/o4+ubx2+IL3fkev22mEN38+dFmYF3zE+hpE7jVxrJpC3EP9PLoFgFPKCuctMnjXmeHoiGs756N5r1Mm1ffZu4H19MSuALJlxQR7VXE/LzxRXDuaB2u9days/6muP6gbGX1ASxbJd/ou8+viHmSC/ioHzNjItVCPaJjDyc6bv+gs1NPCt0qZ69G+JmgHW/PsMMeL4n5bh74g0fJSHqiI9ewEmOG/8bedSREv2XXtKV39STxPweceIOh0k23s3N6+wvuSUAJE7u1LkDo14cobtZ/MCw/QhimYPd1u5HnEJvRhPxz0nVPz0QqL/YQeOkAYk7uzgeb2yPzJ6DBtnTnGDkglekhVzQBFRJdk740LEj6swkJ",
"sig":"c94e74533b482aa8eeeb54ae72a5303e0b21f62909ca43c8ef06b0357412d6f8a92f96e1a205102753777fd25321a58fba3fb384eee114bd53ce6c06a1c22bab"
}
- 原文链接: github.com/nostr-protoco...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~