NIP-04
AES-256-CBC encryption for Nostr direct messages (legacy).
WARNING
NIP-04 is considered legacy. For new applications, prefer NIP-44 which provides authenticated encryption and padding.
Import
ts
import { nip04 } from 'nostr-core'nip04.encrypt
ts
function encrypt(
secretKey: string | Uint8Array,
pubkey: string,
text: string
): stringEncrypts a message using AES-256-CBC with a shared secret derived via ECDH.
| Parameter | Type | Description |
|---|---|---|
secretKey | string | Uint8Array | Your secret key (hex string or 32 bytes) |
pubkey | string | Recipient's public key (64-char hex) |
text | string | Plaintext message |
Returns: string - encrypted payload in the format <base64_ciphertext>?iv=<base64_iv>.
ts
const ciphertext = nip04.encrypt(mySecretKey, recipientPubkey, 'Hello!')
// 'dGVzdA==?iv=AAAAAAAAAAAAAAAAAAAAAA=='nip04.decrypt
ts
function decrypt(
secretKey: string | Uint8Array,
pubkey: string,
data: string
): stringDecrypts a NIP-04 encrypted message.
| Parameter | Type | Description |
|---|---|---|
secretKey | string | Uint8Array | Your secret key (hex string or 32 bytes) |
pubkey | string | Sender's public key (64-char hex) |
data | string | Encrypted payload (ciphertext?iv=iv) |
Returns: string - decrypted plaintext.
Throws: Error on decryption failure.
ts
const plaintext = nip04.decrypt(mySecretKey, senderPubkey, ciphertext)How It Works
- Computes a shared secret via ECDH (
secp256k1.getSharedSecret) - Uses bytes 1–32 of the shared point as the AES key
- Generates a random 16-byte IV
- Encrypts with AES-256-CBC
- Returns
base64(ciphertext)?iv=base64(iv)