NIP-49: Private Key Encryption
This NIP defines a method by which clients can encrypt (and decrypt) a user's private key with a password.
Encrypt a secret key
Firstly, parse or generate a secret key:
Rust
let secret_key: SecretKey = SecretKey::parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")?;
Python
secret_key = SecretKey.parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")
JavaScript
let secretKey: SecretKey = SecretKey.parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683");
Kotlin
val secretKey: SecretKey = SecretKey.parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")
Swift
let secretKey = try SecretKey.parse(secretKey: "3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")
Flutter
SecretKey secretKey = SecretKey.parse(secretKey: "3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683");
Now that we have the SecretKey
, we can encrypt it:
Rust
let password: &str = "nostr";
let encrypted: EncryptedSecretKey = secret_key.encrypt(password)?;
Python
password = "nostr"
encrypted = secret_key.encrypt(password)
JavaScript
let password: string = "nostr";
let encrypted: EncryptedSecretKey = secretKey.encrypt(password);
Kotlin
val password = "nostr"
val encrypted: EncryptedSecretKey = secretKey.encrypt(password)
Swift
let password = "nostr"
let encrypted = try secretKey.encrypt(password: password)
Flutter
final password = "nostr";
EncryptedSecretKey encrypted = secretKey.encrypt(password: password);
In some cases, you may want to customize some encryption values:
Rust
let encrypted: EncryptedSecretKey = EncryptedSecretKey::new(&secret_key, password, 12, KeySecurity::Weak)?;
Python
encrypted_custom = EncryptedSecretKey(secret_key, password, 12, KeySecurity.WEAK)
JavaScript
let encryptedCustom: EncryptedSecretKey = new EncryptedSecretKey(secretKey, password, 12, KeySecurity.Weak);
Kotlin
val encryptedCustom = EncryptedSecretKey(secretKey, password, 12u, KeySecurity.WEAK)
Swift
let encryptedCustom = try EncryptedSecretKey(secretKey: secretKey, password: password, logN: 12, keySecurity: KeySecurity.weak)
Flutter
EncryptedSecretKey encryptedCustom = EncryptedSecretKey(secretKey: secretKey, password: password, logN: 12, keySecurity: EncryptedSecretKeySecurity.weak);
Decrypt a secret key
Let's start by parsing the ncryptsec
string:
Rust
let encrypted: EncryptedSecretKey = EncryptedSecretKey::from_bech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")?;
Python
encrypted = EncryptedSecretKey.from_bech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")
JavaScript
let encrypted: EncryptedSecretKey = EncryptedSecretKey.fromBech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p");
Kotlin
val encrypted: EncryptedSecretKey = EncryptedSecretKey.fromBech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")
Swift
let encrypted = try EncryptedSecretKey.fromBech32(bech32: "ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")
Flutter
EncryptedSecretKey encrypted = EncryptedSecretKey.fromBech32(bech32: "ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p");
Now you can decrypt the secret key:
Rust
let secret_key: SecretKey = encrypted.to_secret_key("nostr")?;
Python
secret_key = encrypted.to_secret_key("nostr")
JavaScript
let secretKey: SecretKey = encrypted.toSecretKey("nostr");
Kotlin
val secretKey: SecretKey = encrypted.toSecretKey(password = "nostr")
Swift
let secretKey = try encrypted.toSecretKey(password: "nostr")
Flutter
SecretKey secretKey = encrypted.decrypt(password: "nostr");
Full example
Here’s the full example that includes all the steps:
Rust
use nostr_sdk::prelude::*;
pub fn encrypt() -> Result<()> {
let secret_key: SecretKey = SecretKey::parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")?;
let password: &str = "nostr";
let encrypted: EncryptedSecretKey = secret_key.encrypt(password)?;
println!("Encrypted secret key: {}", encrypted.to_bech32()?);
let encrypted: EncryptedSecretKey = EncryptedSecretKey::new(&secret_key, password, 12, KeySecurity::Weak)?;
println!("Encrypted secret key (custom): {}", encrypted.to_bech32()?);
Ok(())
}
pub fn decrypt() -> Result<()> {
let encrypted: EncryptedSecretKey = EncryptedSecretKey::from_bech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")?;
let secret_key: SecretKey = encrypted.to_secret_key("nostr")?;
println!("Decrypted secret key: {}", secret_key.to_bech32()?);
Ok(())
}
Python
from nostr_sdk import SecretKey, EncryptedSecretKey, KeySecurity
def encrypt():
secret_key = SecretKey.parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")
password = "nostr"
encrypted = secret_key.encrypt(password)
print(f"Encrypted secret key: {encrypted.to_bech32()}")
encrypted_custom = EncryptedSecretKey(secret_key, password, 12, KeySecurity.WEAK)
print(f"Encrypted secret key (custom): {encrypted_custom.to_bech32()}")
def decrypt():
encrypted = EncryptedSecretKey.from_bech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")
secret_key = encrypted.to_secret_key("nostr")
print(f"Decrypted secret key: {secret_key.to_bech32()}")
JavaScript
import {EncryptedSecretKey, KeySecurity, loadWasmSync, SecretKey} from "@rust-nostr/nostr-sdk";
function encrypt() {
let secretKey: SecretKey = SecretKey.parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683");
let password: string = "nostr";
let encrypted: EncryptedSecretKey = secretKey.encrypt(password);
console.log("Encrypted secret key:", encrypted.toBech32());
let encryptedCustom: EncryptedSecretKey = new EncryptedSecretKey(secretKey, password, 12, KeySecurity.Weak);
console.log("Encrypted secret key (custom):", encryptedCustom.toBech32());
}
function decrypt() {
let encrypted: EncryptedSecretKey = EncryptedSecretKey.fromBech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p");
let secretKey: SecretKey = encrypted.toSecretKey("nostr");
console.log("Decrypted secret key:", secretKey.toBech32());
}
loadWasmSync();
encrypt();
decrypt();
Kotlin
import rust.nostr.sdk.*
fun encrypt() {
val secretKey: SecretKey = SecretKey.parse("3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")
val password = "nostr"
val encrypted: EncryptedSecretKey = secretKey.encrypt(password)
println("Encrypted secret key: ${encrypted.toBech32()}")
val encryptedCustom = EncryptedSecretKey(secretKey, password, 12u, KeySecurity.WEAK)
println("Encrypted secret key (custom): ${encryptedCustom.toBech32()}")
}
fun decrypt() {
val encrypted: EncryptedSecretKey = EncryptedSecretKey.fromBech32("ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")
val secretKey: SecretKey = encrypted.toSecretKey(password = "nostr")
println("Decrypted secret key: ${secretKey.toBech32()}")
}
fun main() {
encrypt()
decrypt()
}
Swift
import Foundation
import NostrSDK
func encrypt() throws {
let secretKey = try SecretKey.parse(secretKey: "3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683")
let password = "nostr"
let encrypted = try secretKey.encrypt(password: password)
print("Encrypted secret key: \(try encrypted.toBech32())")
let encryptedCustom = try EncryptedSecretKey(secretKey: secretKey, password: password, logN: 12, keySecurity: KeySecurity.weak)
print("Encrypted secret key (custom): \(try encryptedCustom.toBech32())")
}
func decrypt() throws {
let encrypted = try EncryptedSecretKey.fromBech32(bech32: "ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p")
let secretKey = try encrypted.toSecretKey(password: "nostr")
print("Decrypted secret key: \(try secretKey.toBech32())")
}
Flutter
import 'package:nostr_sdk/nostr_sdk.dart';
void encrypt() {
SecretKey secretKey = SecretKey.parse(secretKey: "3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683");
final password = "nostr";
EncryptedSecretKey encrypted = secretKey.encrypt(password: password);
print("Encrypted secret key: ${encrypted.toBech32()}");
EncryptedSecretKey encryptedCustom = EncryptedSecretKey(secretKey: secretKey, password: password, logN: 12, keySecurity: EncryptedSecretKeySecurity.weak);
print("Encrypted secret key (custom): ${encryptedCustom.toBech32()}");
}
void restore() {
EncryptedSecretKey encrypted = EncryptedSecretKey.fromBech32(bech32: "ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p");
SecretKey secretKey = encrypted.decrypt(password: "nostr");
print("Decrypted secret key: ${secretKey.toBech32()}");
}