# NIP04

## 加密的直接消息

`final` `optional` `author:arcbtc`

带有 kind `4` 的特殊事件，表示"加密的直接消息"。它应该具有以下属性：

\*\* `content` \*\*必须等于用户想要写入的任何内容的 base64 编码、AES-256-CBC 加密字符串，使用接收方的公钥和发送方的私钥组合生成的共享密码进行加密；这由 Base64 编码的初始化向量附加，就好像它是一个名为" IV "的查询字符串参数。格式如下： `"content": "<encrypted_text>?iv=<initialization_vector>"`。

\*\* `tags` \*\*必须包含标识消息接收者的条目（以便中继可以自然地将此事件转发给它们），格式 `["p", "<pubkey, as a hex string>"]` 为。

\*\* `tags` \*\*可能包含一个条目，该条目标识对话中的前一条消息或我们明确回复的消息（以便可能发生上下文相关的、更有组织的对话），格式 `["e", "<event_id>"]` 为。

**注意**：默认情况下，在[libsecp256k1](https://github.com/bitcoin-core/secp256k1)ECDH 实现中，秘密是共享点的 SHA256 哈希（X 和 Y 坐标）。在 NOSTR 中，仅将共享点的 X 坐标用作秘密，并且不对其进行散列。如果使用 libsecp256k1，则必须将复制 X 坐标的自定义函数作为中 `secp256k1_ecdh` 的 `hashfp` 参数传递。看吧[here](https://github.com/bitcoin-core/secp256k1/blob/master/src/modules/ecdh/main_impl.h#L29)。

在 JavaScript 中生成此类事件的代码示例：

```js
import crypto from 'crypto'
import * as secp from '@noble/secp256k1'

let sharedPoint = secp.getSharedSecret(ourPrivateKey, '02' + theirPublicKey)
let sharedX = sharedPoint.slice(1, 33)

let iv = crypto.randomFillSync(new Uint8Array(16))
var cipher = crypto.createCipheriv(
  'aes-256-cbc',
  Buffer.from(sharedX),
  iv
)
let encryptedMessage = cipher.update(text, 'utf8', 'base64')
encryptedMessage += cipher.final('base64')
let ivBase64 = Buffer.from(iv.buffer).toString('base64')

let event = {
  pubkey: ourPubKey,
  created_at: Math.floor(Date.now() / 1000),
  kind: 4,
  tags: [['p', theirPublicKey]],
  content: encryptedMessage + '?iv=' + ivBase64
}
```

## 安全警告

该标准在对等体之间的加密通信中并不被认为是最先进的，并且它会泄漏事件中的元数据，因此它不能用于你真正需要保密的任何事情，并且只能用于限制谁可以获取你的 `kind:4` 事件的中继 `AUTH`。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sherry-pang.gitbook.io/nostr-cn/fu-lu-1-nip-xiang-jie/04.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
