github.com/lino-network/lino@v0.6.11/client/encrypt/encrypt.go (about)

     1  package encrypt
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/rand"
     7  	"crypto/sha256"
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  	"os"
    12  
    13  	"golang.org/x/crypto/ssh/terminal"
    14  )
    15  
    16  func hashPassword(pw string) []byte {
    17  	hash := sha256.Sum256([]byte(pw))
    18  	return hash[:]
    19  }
    20  
    21  func Encrypt(data []byte, password string) ([]byte, error) {
    22  	block, err := aes.NewCipher(hashPassword(password))
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	gcm, err := cipher.NewGCM(block)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	nonce := make([]byte, gcm.NonceSize())
    31  	if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
    32  		return nil, err
    33  	}
    34  	cipher := gcm.Seal(nonce, nonce, data, nil)
    35  	return cipher, nil
    36  }
    37  
    38  func Decrypt(data []byte, password string) ([]byte, error) {
    39  	block, err := aes.NewCipher(hashPassword(password))
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	gcm, err := cipher.NewGCM(block)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	nonceSize := gcm.NonceSize()
    48  	nonce, ciphertext := data[:nonceSize], data[nonceSize:]
    49  	return gcm.Open(nil, nonce, ciphertext, nil)
    50  }
    51  
    52  func EncryptToFile(filename string, data []byte, password string) error {
    53  	cipher, err := Encrypt(data, password)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	f, err := os.Create(filename)
    59  	if err != nil {
    60  		return err
    61  	}
    62  	defer f.Close()
    63  
    64  	_, err = f.Write(cipher)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	return f.Sync()
    69  }
    70  
    71  func DecryptFromFile(filename string, password string) ([]byte, error) {
    72  	data, err := ioutil.ReadFile(filename)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	return Decrypt(data, password)
    77  }
    78  
    79  func DecryptByStdin(filename string) ([]byte, error) {
    80  	fmt.Printf("Password of %s: ", filename)
    81  	pw, err := terminal.ReadPassword(0)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	fmt.Printf("\n")
    86  	return DecryptFromFile(filename, string(pw))
    87  }