feat: Rename password by encryption key
All checks were successful
/ pre-commit (push) Successful in 1m9s
All checks were successful
/ pre-commit (push) Successful in 1m9s
Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
parent
634326190c
commit
8e1dd686d3
16 changed files with 118 additions and 117 deletions
|
@ -19,21 +19,21 @@ const (
|
|||
|
||||
// NewCipher creates a cipher using XChaCha20-Poly1305
|
||||
// https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305
|
||||
// A salt is required to derive the key from a password using argon
|
||||
func NewCipher(password string, salt []byte) (cipher.AEAD, error) {
|
||||
key := argon2.IDKey([]byte(password), salt, KeyTime, KeyMemory, KeyThreads, KeySize)
|
||||
// A salt is required to derive the key from an encryption key using argon
|
||||
func NewCipher(encryptionKey string, salt []byte) (cipher.AEAD, error) {
|
||||
key := argon2.IDKey([]byte(encryptionKey), salt, KeyTime, KeyMemory, KeyThreads, KeySize)
|
||||
return chacha20poly1305.NewX(key)
|
||||
}
|
||||
|
||||
// Encrypt to encrypt a plaintext with a password
|
||||
// Encrypt to encrypt a plaintext with an encryption key
|
||||
// Returns a byte slice with the generated salt, nonce and the ciphertext
|
||||
func Encrypt(plaintext []byte, password string) (result []byte, err error) {
|
||||
func Encrypt(plaintext []byte, encryptionKey string) (result []byte, err error) {
|
||||
salt := make([]byte, SaltSize)
|
||||
if n, err := rand.Read(salt); err != nil || n != SaltSize {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aead, err := NewCipher(password, salt)
|
||||
aead, err := NewCipher(encryptionKey, salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -53,15 +53,15 @@ func Encrypt(plaintext []byte, password string) (result []byte, err error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
// Decrypt to decrypt a ciphertext with a password
|
||||
// Decrypt to decrypt a ciphertext with a encryption key
|
||||
// Returns the plaintext
|
||||
func Decrypt(ciphertext []byte, password string) ([]byte, error) {
|
||||
func Decrypt(ciphertext []byte, encryptionKey string) ([]byte, error) {
|
||||
if len(ciphertext) < SaltSize {
|
||||
return nil, fmt.Errorf("ciphertext is too short: cannot read salt")
|
||||
}
|
||||
salt := ciphertext[:SaltSize]
|
||||
|
||||
aead, err := NewCipher(password, salt)
|
||||
aead, err := NewCipher(encryptionKey, salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ import (
|
|||
|
||||
func TestEncryptAndDecrypt(t *testing.T) {
|
||||
plaintext := "test"
|
||||
password := "test"
|
||||
wrongPassword := password + "wrong"
|
||||
encryptionKey := "test"
|
||||
wrongEncryptionKey := encryptionKey + "wrong"
|
||||
|
||||
ciphertext, err := Encrypt([]byte(plaintext), password)
|
||||
ciphertext, err := Encrypt([]byte(plaintext), encryptionKey)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when encrypting: %v", err)
|
||||
return
|
||||
|
@ -20,7 +20,7 @@ func TestEncryptAndDecrypt(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
cleartext, err := Decrypt(ciphertext, password)
|
||||
cleartext, err := Decrypt(ciphertext, encryptionKey)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when decrypting: %v", err)
|
||||
return
|
||||
|
@ -31,14 +31,14 @@ func TestEncryptAndDecrypt(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
if password == wrongPassword {
|
||||
t.Errorf("passwords must be different")
|
||||
if encryptionKey == wrongEncryptionKey {
|
||||
t.Errorf("encryption keys must be different")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = Decrypt(ciphertext, wrongPassword)
|
||||
_, err = Decrypt(ciphertext, wrongEncryptionKey)
|
||||
if err == nil {
|
||||
t.Errorf("expected error when decrypting with a wrong password, got none")
|
||||
t.Errorf("expected error when decrypting with a wrong encryption key, got none")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package internal
|
||||
|
||||
const (
|
||||
RC_OK = 0
|
||||
RC_ERROR = 1
|
||||
MIN_PASSWORD_LENGTH = 16
|
||||
MAX_PASSWORD_LENGTH = 256
|
||||
RC_OK = 0
|
||||
RC_ERROR = 1
|
||||
MIN_ENCRYPTION_KEY_LENGTH = 16
|
||||
MAX_ENCRYPTION_KEY_LENGTH = 256
|
||||
)
|
||||
|
|
|
@ -58,13 +58,13 @@ func GenerateChars(n int) string {
|
|||
return string(b)
|
||||
}
|
||||
|
||||
// Passwords must be URL compatible and strong enough
|
||||
// Encryption key must be URL compatible and strong enough
|
||||
// Requiring only alphanumeric chars with a size between 16 and 256
|
||||
var passwordRegexp = regexp.MustCompile("^[a-zA-Z0-9]{16,256}$")
|
||||
var encryptionKeyRegexp = regexp.MustCompile("^[a-zA-Z0-9]{16,256}$")
|
||||
|
||||
func ValidatePassword(p string) error {
|
||||
if !passwordRegexp.MatchString(p) {
|
||||
return fmt.Errorf("password doesn't match '%s'", passwordRegexp)
|
||||
func ValidateEncryptionKey(p string) error {
|
||||
if !encryptionKeyRegexp.MatchString(p) {
|
||||
return fmt.Errorf("encryption key doesn't match '%s'", encryptionKeyRegexp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue