diff --git a/encrypt_decrypt.go b/encrypt_decrypt.go new file mode 100644 index 0000000..8ef39e7 --- /dev/null +++ b/encrypt_decrypt.go @@ -0,0 +1,140 @@ +package main + +import ( + "context" + "fmt" + + "github.com/fiatjaf/cli/v3" + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/nip04" +) + +var encrypt = &cli.Command{ + Name: "encrypt", + Usage: "encrypts a string with nip44 (or nip04 if specified using a flag) and returns the resulting ciphertext as base64", + ArgsUsage: "[plaintext string]", + DisableSliceFlagSeparator: true, + Flags: append( + defaultKeyFlags, + &cli.StringFlag{ + Name: "recipient-pubkey", + Aliases: []string{"p", "tgt", "target", "pubkey"}, + Required: true, + }, + &cli.BoolFlag{ + Name: "nip04", + Usage: "use nip04 encryption instead of nip44", + }, + ), + Action: func(ctx context.Context, c *cli.Command) error { + target := c.String("recipient-pubkey") + if !nostr.IsValidPublicKey(target) { + return fmt.Errorf("target %s is not a valid public key", target) + } + + plaintext := c.Args().First() + + if c.Bool("nip04") { + sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(ctx, c) + if err != nil { + return err + } + + if bunker != nil { + ciphertext, err := bunker.NIP04Encrypt(ctx, target, plaintext) + if err != nil { + return err + } + fmt.Println(ciphertext) + } else { + ss, err := nip04.ComputeSharedSecret(target, sec) + if err != nil { + return fmt.Errorf("failed to compute nip04 shared secret: %w", err) + } + ciphertext, err := nip04.Encrypt(plaintext, ss) + if err != nil { + return fmt.Errorf("failed to encrypt as nip04: %w", err) + } + fmt.Println(ciphertext) + } + } else { + kr, err := gatherKeyerFromArguments(ctx, c) + if err != nil { + return err + } + + res, err := kr.Encrypt(ctx, plaintext, target) + if err != nil { + return fmt.Errorf("failed to encrypt: %w", err) + } + fmt.Println(res) + } + + return nil + }, +} + +var decrypt = &cli.Command{ + Name: "decrypt", + Usage: "decrypts a base64 nip44 ciphertext (or nip04 if specified using a flag) and returns the resulting plaintext", + ArgsUsage: "[ciphertext base64]", + DisableSliceFlagSeparator: true, + Flags: append( + defaultKeyFlags, + &cli.StringFlag{ + Name: "sender-pubkey", + Aliases: []string{"p", "src", "source", "pubkey"}, + Required: true, + }, + &cli.BoolFlag{ + Name: "nip04", + Usage: "use nip04 encryption instead of nip44", + }, + ), + Action: func(ctx context.Context, c *cli.Command) error { + source := c.String("sender-pubkey") + if !nostr.IsValidPublicKey(source) { + return fmt.Errorf("source %s is not a valid public key", source) + } + + ciphertext := c.Args().First() + + if c.Bool("nip04") { + sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(ctx, c) + if err != nil { + return err + } + + if bunker != nil { + plaintext, err := bunker.NIP04Decrypt(ctx, source, ciphertext) + if err != nil { + return err + } + fmt.Println(plaintext) + } else { + ss, err := nip04.ComputeSharedSecret(source, sec) + if err != nil { + return fmt.Errorf("failed to compute nip04 shared secret: %w", err) + } + plaintext, err := nip04.Decrypt(ciphertext, ss) + if err != nil { + return fmt.Errorf("failed to encrypt as nip04: %w", err) + } + fmt.Println(plaintext) + } + } else { + kr, err := gatherKeyerFromArguments(ctx, c) + if err != nil { + return err + } + + res, err := kr.Decrypt(ctx, ciphertext, source) + if err != nil { + return fmt.Errorf("failed to encrypt: %w", err) + } + fmt.Println(res) + } + + return nil + }, +} diff --git a/key.go b/key.go index d925ba6..826cb7f 100644 --- a/key.go +++ b/key.go @@ -25,8 +25,8 @@ var key = &cli.Command{ Commands: []*cli.Command{ generate, public, - encrypt, - decrypt, + encryptKey, + decryptKey, combine, }, } @@ -62,7 +62,7 @@ var public = &cli.Command{ }, } -var encrypt = &cli.Command{ +var encryptKey = &cli.Command{ Name: "encrypt", Usage: "encrypts a secret key and prints an ncryptsec code", Description: `uses the NIP-49 standard.`, @@ -101,7 +101,7 @@ var encrypt = &cli.Command{ }, } -var decrypt = &cli.Command{ +var decryptKey = &cli.Command{ Name: "decrypt", Usage: "takes an ncrypsec and a password and decrypts it into an nsec", Description: `uses the NIP-49 standard.`, diff --git a/main.go b/main.go index 218e5f2..aae4e37 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,8 @@ var app = &cli.Command{ relay, bunker, serve, + encrypt, + decrypt, }, Version: version, Flags: []cli.Flag{