github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/util/crypt.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package util
     7  
     8  import (
     9  	"crypto/aes"
    10  	"crypto/cipher"
    11  	"crypto/rand"
    12  	"crypto/sha256"
    13  	"fmt"
    14  	"io"
    15  )
    16  
    17  // HashSHA256 will compute a cryptographically useful hash of the input string.
    18  func HashSHA256(input []byte) []byte {
    19  	data := sha256.Sum256(input)
    20  	return data[:]
    21  }
    22  
    23  // Decrypt Takes two strings, data and key.
    24  // data is the text to be decrypted and the key is the key to use for the decryption.
    25  // The function will output the resulting plain text string with an error variable.
    26  func Decrypt(data, key []byte) ([]byte, error) {
    27  	if len(data) < aes.BlockSize {
    28  		return nil, fmt.Errorf("cipherText too short. It decodes to %v bytes but the minimum length is 16", len(data))
    29  	}
    30  	// split the input up in to the IV seed and then the actual encrypted data.
    31  	iv := data[:aes.BlockSize]
    32  	data = data[aes.BlockSize:]
    33  
    34  	block, err := aes.NewCipher(key)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	stream := cipher.NewCFBDecrypter(block, iv)
    39  
    40  	stream.XORKeyStream(data, data)
    41  	return data, nil
    42  }
    43  
    44  // Encrypt Takes two string, data and key.
    45  // data is the text that needs to be encrypted by key.
    46  // The function will output the resulting crypto text and an error variable.
    47  func Encrypt(data, key []byte) ([]byte, error) {
    48  	block, err := aes.NewCipher(key)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	// create two 'windows' in to the output slice.
    54  	output := make([]byte, aes.BlockSize+len(data))
    55  	iv := output[:aes.BlockSize]
    56  	encrypted := output[aes.BlockSize:]
    57  
    58  	// populate the IV slice with random data.
    59  	if _, err = io.ReadFull(rand.Reader, iv); err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	stream := cipher.NewCFBEncrypter(block, iv)
    64  
    65  	// note that encrypted is still a window in to the output slice
    66  	stream.XORKeyStream(encrypted, data)
    67  	return output, nil
    68  }