Community

NIPs

NIP-49: Private Key Encryption (ncryptsec)

NIP-49 defines ncryptsec, an encrypted export format for a Nostr private key using password-based scrypt derivation and XChaCha20-Poly1305.

NIP-49: Private Key Encryption (ncryptsec) visual
NIPs Under the hood Events, NIPs, relay behavior and the shared formats apps can trust.
Back to Nostr
NIPs Open NIP map Deep guidesConcepts, NIP pages and source checks BrowseClose
Identity and signingdraftoptionalkey storage

NIP-49: Private Key Encryption (ncryptsec)

NIP49Statusdraft / optionalPrefixncryptsecKDFscryptCipherXChaCha20-Poly1305Password ruleUnicode NFKC normalization

People need backups that are not naked nsecs

A raw nsec is dangerously easy to copy, paste, screenshot, sync and lose. Nostr needs better signers, but people also need backups and imports. NIP-49 fills that narrow gap: an encrypted private-key export format that can move between clients without exposing the private key in plain text.

The output is a bech32 string with the prefix ncryptsec. It is not magic custody. It is a password-encrypted container around the 32-byte secp256k1 secret key, designed so clients can import and export keys in a common format.

This NIP matters because key management is one of the main barriers to sane Nostr use. Remote signing reduces where a key has to live. NIP-49 helps when a key still has to be stored, backed up or moved.

scrypt, security byte, nonce and bech32 packaging

The password is normalized to Unicode NFKC before key derivation. That sounds obscure until someone creates a password with visually similar characters on one device and tries to decrypt it on another. NFKC reduces those cross-client surprises.

The symmetric key is derived with scrypt using a 16-byte random salt, r=8, p=1 and a configurable log_n work factor. The NIP gives memory and approximate-time guidance for values such as 16, 18, 20, 21 and 22. Higher values are more expensive and more resistant to brute force, but not all devices can comfortably use them.

The encrypted payload includes a version byte, log_n byte, salt, 24-byte nonce, associated data and ciphertext. The associated data is a key-security byte: known insecure handling, not known insecure, or client does not track this data. That byte is a small but thoughtful attempt to keep history attached to the key export.

A compact format with one important breaking correction

NIP-49 was added in January 2024 by Michael Dilger. In February 2024, Mike Dilger changed the password rule so passwords are normalized to Unicode NFKC before derivation. That was a breaking correction, but the kind of correction a key-storage format needs early.

The same month added a test vector for Unicode normalization. In June 2026, fiatjaf renamed several NIPs for clarity, which is why the title now explicitly names private key encryption and ncryptsec.

The history is short because the format is intentionally narrow. It is not a wallet, signer, recovery protocol or account migration service. It is a concrete encrypted export shape.

First visible addition2024-01-30 by Michael DilgerBreaking normalization fixNFKC password normalization in February 2024Open Git history

The UX must respect the cryptography

A client implementing NIP-49 needs to make three things clear. First, the password protects the export, so weak passwords remain weak. Second, the work factor affects unlock time and device memory. Third, an encrypted export is still sensitive and must not be sprayed across unsafe storage casually.

Rust-nostr and related Rust documentation include NIP-49 support. There are also issue threads in projects such as nos2x and libnostr-z around storing or adding ncryptsec support. Those discussions show why the standard exists: users and client developers keep looking for a safer alternative to visible raw keys.

A good UI does not say your key is safe now. It says this is an encrypted private-key export, tells the user where it is stored, lets them choose or understand a work factor, and keeps private-key material out of logs, clipboard history and screenshots.

ncryptsecBech32-encoded encrypted secret-key container.
scryptMemory-hard password derivation with configurable log_n.
XChaCha20-Poly1305Authenticated encryption for the 32-byte private key.
User warningPassword quality and storage hygiene still matter.

Encrypted export can create false comfort

NIP-49 reduces the danger of a raw nsec, but it does not remove human risk. A short password can be attacked. A cloud-synced export can be stolen. A device can leak clipboard data. A client can use a work factor too low for the user's threat model.

There is also an interoperability risk around password normalization. If one client skips NFKC or mishandles Unicode, a user may believe their backup is broken. Test vectors are not optional niceties here; they are the way clients avoid locking users out of their own identity.

Read NIP-49 in the wild

NIP-49 gives private keys an encrypted export format. That is useful for backup, device transfer and safer storage when a raw nsec would be too exposed.

The danger is comfort. An encrypted key file still depends on passphrase strength, storage location and recovery habits. If the product makes backup feel solved while hiding those limits, people will lose identities with better-looking files.

What changes when you actually use it

For you, NIP-49: Private Key Encryption (ncryptsec) is felt when identity stops being a username and becomes authority. A client, signer, name, proof or auth event may look like account plumbing, but it decides who can publish, approve, connect, recover or be recognized. Read NIP-01 and the adjacent source links beside it so you can tell the difference between a convenient identity surface and the key material that actually controls the account.

What changes for builders and operators

For builders, NIP-49: Private Key Encryption (ncryptsec) means making authority visible before action. A signer prompt, name proof, delegation, encrypted key, external identity or HTTP auth event needs plain language around scope, expiry, destination and recovery. If a person has to guess what they are authorizing, the protocol has already lost the trust battle.

What the official file makes concrete

The official file is organized around Password Unicode Normalization, Encryption, Decryption, On Key Derivation, On the symmetric encryption algorithm. Inspect draft because these are the pieces most likely to surface as product behavior.

NIP-49: Private Key Encryption (ncryptsec) is an authority path, not decoration. A name, key, signer, delegation or auth event decides who can act as you.

Where it breaks

The failure mode in NIP-49: Private Key Encryption (ncryptsec) is authority drift. A name resolves to an old key, a signer approves too broadly, an auth event gets replayed, a delegation lasts too long or a private key backup gives false comfort. The product has to keep control boundaries visible after onboarding, not only during setup.

Where this appears outside the markdown

In the ecosystem, NIP-49: Private Key Encryption (ncryptsec) usually appears at the doorway: account setup, profile recognition, signer approval, cross-platform proof, remote signing, HTTP auth or recovery. That doorway needs unusually clear language because identity mistakes are sticky. Once a key, signer or proof is trusted in the wrong place, every later feature inherits the confusion.

The nearby-standard trap

The nearby-standard trap in NIP-49: Private Key Encryption (ncryptsec) is confusing recognition with control. A name, signer, URI, encrypted key, delegation or auth signature may all sit near identity, but they answer different questions. Read NIP-01 and the adjacent source links and ask one thing each time: who can act, who can verify, and what can be revoked?

Language that keeps the feature honest

Good product copy for NIP-49: Private Key Encryption (ncryptsec) names the authority. It says whether you are sharing a public key, approving a signature, trusting a domain, exporting an encrypted secret, delegating power or authenticating to a service. Small labels matter because identity mistakes do not feel small after they happen.

What this page does not promise

NIP-49: Private Key Encryption (ncryptsec) does not make identity effortless or risk-free. It can help keys, names, signers, delegation or authentication become portable, but it cannot decide who you trust, how you back up secrets or whether a domain, app or signer deserves authority. Read NIP-01 and the adjacent source links as a control map before handing any interface the power to sign, verify or speak for you.

Read it as a field test

Start NIP-49: Private Key Encryption (ncryptsec) with the moment of authority: signing, naming, delegation, authentication, encryption or recovery. Then ask which key or service can act. The source terms draft are useful because they turn vague identity language into concrete control points. Without that, a friendly login screen can hide the most important security decision.

Where the standard earns trust

The source links give you places to test the interpretation in public: Rust Nostr Book: NIP-49, nos2x ncryptsec issue, libnostr-z NIP-49 issue, RFC 7914 scrypt. Use those links to move from the spec to live libraries, mirrors, pull requests, guides or products.

Official NIP-49 source is the anchor for exact wording, and NIP-49 commit history shows how that wording moved over time. The strongest secondary clues here are Rust Nostr Book: NIP-49, nos2x ncryptsec issue, libnostr-z NIP-49 issue. Treat this evidence chain as part of the article, not as footnotes. A NIP page becomes useful when you can move from claim to source to working behavior without guessing.

Keep the chain visible for NIP-49: Private Key Encryption (ncryptsec): first the human promise, then draft, then the implementation record, then the real-world failure case. That order keeps NIP-49 useful without turning it into marketing copy or protocol trivia.

Three questions to carry forward

  • Who gains authority when this NIP is used: your key, a signer, a domain, a delegated key, a wallet or a web service?
  • Can you revoke, rotate, back up or inspect that authority before something goes wrong?
  • Does the interface separate public recognition from private signing power in language you can act on?

What to verify before you rely on it

  • Find draft in the official file and check where the UI exposes the same concept.
  • Read NIP-01 and the adjacent source links as context before treating NIP-49 as a complete product story.
  • Open at least one implementation, mirror, pull request or library source from the source links before trusting that the idea is mature.
  • Test the unhappy path: missing relays, stale metadata, invalid signatures, blocked events, expired state, revoked permissions or unavailable media.
  • Write the user-facing copy in plain language. If a standard changes authority, privacy, money, moderation or recovery, say that before the click.

Direct sources

Use these sources for NIP-49: Private Key Encryption (ncryptsec) in that order: Official NIP-49 source for the current wording; NIP-49 commit history for the change record; Rust Nostr Book: NIP-49, nos2x ncryptsec issue, libnostr-z NIP-49 issue for public context. The article gives you the consequence in plain language, but the source trail is where exact fields, status notes, unresolved debates and implementation proof stay checkable.

Back to the NIP hub
NIPs route visual cue 1
NIPs route visual cue 2
NIPs route visual cue 3
NIPs route visual cue 4
NIPs route visual cue 5