mirror of
https://github.com/Luzifer/go-openssl.git
synced 2024-12-20 19:01:18 +00:00
Add salt validation and improve comments
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
317731a683
commit
54263e5c8a
2 changed files with 38 additions and 5 deletions
24
openssl.go
24
openssl.go
|
@ -7,10 +7,13 @@ import (
|
|||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
var ErrInvalidSalt = errors.New("Salt needs to have exactly 8 byte")
|
||||
|
||||
// OpenSSL is a helper to generate OpenSSL compatible encryption
|
||||
// with autmatic IV derivation and storage. As long as the key is known all
|
||||
// data can also get decrypted using OpenSSL CLI.
|
||||
|
@ -70,8 +73,9 @@ func (o *OpenSSL) decrypt(key, iv, data []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
// EncryptString encrypts a string in a manner compatible to OpenSSL encryption
|
||||
// functions using AES-256-CBC as encryption algorithm. Generating salt.
|
||||
func (o *OpenSSL) EncryptString(passphrase string, plaintextString string) ([]byte, error) {
|
||||
// functions using AES-256-CBC as encryption algorithm. This function generates
|
||||
// a random salt on every execution.
|
||||
func (o *OpenSSL) EncryptString(passphrase, plaintextString string) ([]byte, error) {
|
||||
salt := make([]byte, 8) // Generate an 8 byte salt
|
||||
_, err := io.ReadFull(rand.Reader, salt)
|
||||
if err != nil {
|
||||
|
@ -81,10 +85,20 @@ func (o *OpenSSL) EncryptString(passphrase string, plaintextString string) ([]by
|
|||
return o.EncryptStringWithSalt(passphrase, salt, plaintextString)
|
||||
}
|
||||
|
||||
// EncryptString encrypts a string in a manner compatible to OpenSSL encryption
|
||||
// functions using AES-256-CBC as encryption algorithm. Ability to pass custom
|
||||
// salt.
|
||||
// EncryptStringWithSalt encrypts a string in a manner compatible to OpenSSL
|
||||
// encryption functions using AES-256-CBC as encryption algorithm. The salt
|
||||
// needs to be passed in here which ensures the same result on every execution
|
||||
// on cost of a much weaker encryption as with EncryptString.
|
||||
//
|
||||
// The salt passed into this function needs to have exactly 8 byte.
|
||||
//
|
||||
// If you don't have a good reason to use this, please don't! For more information
|
||||
// see this: https://en.wikipedia.org/wiki/Salt_(cryptography)#Common_mistakes
|
||||
func (o *OpenSSL) EncryptStringWithSalt(passphrase string, salt []byte, plaintextString string) ([]byte, error) {
|
||||
if len(salt) != 8 {
|
||||
return nil, ErrInvalidSalt
|
||||
}
|
||||
|
||||
data := make([]byte, len(plaintextString)+aes.BlockSize)
|
||||
copy(data[0:], o.openSSLSaltHeader)
|
||||
copy(data[8:], salt)
|
||||
|
|
|
@ -119,3 +119,22 @@ func TestEncryptToOpenSSL(t *testing.T) {
|
|||
t.Errorf("OpenSSL output did not match input.\nOutput was: %s", out.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaltValidation(t *testing.T) {
|
||||
plaintext := "hallowelt"
|
||||
passphrase := "z4yH36a6zerhfE5427ZV"
|
||||
|
||||
o := New()
|
||||
|
||||
if _, err := o.EncryptStringWithSalt(passphrase, []byte("12345"), plaintext); err != ErrInvalidSalt {
|
||||
t.Errorf("5-character salt was accepted, needs to have 8 character")
|
||||
}
|
||||
|
||||
if _, err := o.EncryptStringWithSalt(passphrase, []byte("1234567890"), plaintext); err != ErrInvalidSalt {
|
||||
t.Errorf("10-character salt was accepted, needs to have 8 character")
|
||||
}
|
||||
|
||||
if _, err := o.EncryptStringWithSalt(passphrase, []byte{0xcb, 0xd5, 0x1a, 0x3, 0x84, 0xba, 0xa8, 0xc8}, plaintext); err == ErrInvalidSalt {
|
||||
t.Errorf("Salt with 8 byte unprintable characters was not accepted")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue