mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-06-05 12:39:36 +02:00
nip49: encrypt before decrypt.
This commit is contained in:
parent
84134f7d8e
commit
58ff5f6716
@ -19,6 +19,50 @@ const (
|
|||||||
ClientDoesNotTrackThisData KeySecurityByte = 0x02
|
ClientDoesNotTrackThisData KeySecurityByte = 0x02
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Encrypt(secretKey string, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
||||||
|
skb, err := hex.DecodeString(secretKey)
|
||||||
|
if err != nil || len(skb) != 32 {
|
||||||
|
return "", fmt.Errorf("invalid secret key")
|
||||||
|
}
|
||||||
|
return EncryptBytes(skb, password, logn, ksb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncryptBytes(secretKey []byte, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
||||||
|
salt := make([]byte, 16)
|
||||||
|
if _, err := rand.Read(salt); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to read salt: %w", err)
|
||||||
|
}
|
||||||
|
n := int(math.Pow(2, float64(int(logn))))
|
||||||
|
key, err := scrypt.Key([]byte(password), salt, n, 8, 1, 32)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to compute key with scrypt: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
concat := make([]byte, 91)
|
||||||
|
concat[0] = 0x02
|
||||||
|
concat[1] = byte(logn)
|
||||||
|
copy(concat[2:2+16], salt)
|
||||||
|
rand.Read(concat[2+16 : 2+16+24]) // nonce
|
||||||
|
ad := []byte{byte(ksb)}
|
||||||
|
copy(concat[2+16+24:2+16+24+1], ad)
|
||||||
|
|
||||||
|
c2p1, err := chacha20poly1305.NewX(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to start xchacha20poly1305: %w", err)
|
||||||
|
}
|
||||||
|
ciphertext := c2p1.Seal(nil, concat[2+16:2+16+24], secretKey, ad)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to encrypt: %w", err)
|
||||||
|
}
|
||||||
|
copy(concat[2+16+24+1:], ciphertext)
|
||||||
|
|
||||||
|
bits5, err := bech32.ConvertBits(concat, 8, 5, true)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return bech32.Encode("ncryptsec", bits5)
|
||||||
|
}
|
||||||
|
|
||||||
func Decrypt(bech32string string, password string) (secretKey string, err error) {
|
func Decrypt(bech32string string, password string) (secretKey string, err error) {
|
||||||
secb, err := DecryptToBytes(bech32string, password)
|
secb, err := DecryptToBytes(bech32string, password)
|
||||||
return hex.EncodeToString(secb), err
|
return hex.EncodeToString(secb), err
|
||||||
@ -63,47 +107,3 @@ func DecryptToBytes(bech32string string, password string) (secretKey []byte, err
|
|||||||
|
|
||||||
return c2p1.Open(nil, nonce, encryptedKey, ad)
|
return c2p1.Open(nil, nonce, encryptedKey, ad)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Encrypt(secretKey string, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
|
||||||
skb, err := hex.DecodeString(secretKey)
|
|
||||||
if err != nil || len(skb) != 32 {
|
|
||||||
return "", fmt.Errorf("invalid secret key")
|
|
||||||
}
|
|
||||||
return EncryptBytes(skb, password, logn, ksb)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EncryptBytes(secretKey []byte, password string, logn uint8, ksb KeySecurityByte) (b32code string, err error) {
|
|
||||||
salt := make([]byte, 16)
|
|
||||||
if _, err := rand.Read(salt); err != nil {
|
|
||||||
return "", fmt.Errorf("failed to read salt: %w", err)
|
|
||||||
}
|
|
||||||
n := int(math.Pow(2, float64(int(logn))))
|
|
||||||
key, err := scrypt.Key([]byte(password), salt, n, 8, 1, 32)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to compute key with scrypt: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
concat := make([]byte, 91)
|
|
||||||
concat[0] = 0x02
|
|
||||||
concat[1] = byte(logn)
|
|
||||||
copy(concat[2:2+16], salt)
|
|
||||||
rand.Read(concat[2+16 : 2+16+24]) // nonce
|
|
||||||
ad := []byte{byte(ksb)}
|
|
||||||
copy(concat[2+16+24:2+16+24+1], ad)
|
|
||||||
|
|
||||||
c2p1, err := chacha20poly1305.NewX(key)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to start xchacha20poly1305: %w", err)
|
|
||||||
}
|
|
||||||
ciphertext := c2p1.Seal(nil, concat[2+16:2+16+24], secretKey, ad)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to encrypt: %w", err)
|
|
||||||
}
|
|
||||||
copy(concat[2+16+24+1:], ciphertext)
|
|
||||||
|
|
||||||
bits5, err := bech32.ConvertBits(concat, 8, 5, true)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return bech32.Encode("ncryptsec", bits5)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user