github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/sm4/utils.go (about)

     1  package sm4
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/x509"
     6  	"encoding/pem"
     7  	"errors"
     8  	"io/ioutil"
     9  )
    10  
    11  // ReadKeyFromPem will return SM4Key from PEM format data.
    12  func ReadKeyFromPem(data []byte, pwd []byte) (SM4Key, error) {
    13  	block, _ := pem.Decode(data)
    14  	if block == nil {
    15  		return nil, errors.New("SM4: pem decode failed")
    16  	}
    17  	if x509.IsEncryptedPEMBlock(block) {
    18  		if block.Type != "SM4 ENCRYPTED KEY" {
    19  			return nil, errors.New("SM4: unknown type")
    20  		}
    21  		if pwd == nil {
    22  			return nil, errors.New("SM4: need passwd")
    23  		}
    24  		data, err := x509.DecryptPEMBlock(block, pwd)
    25  		if err != nil {
    26  			return nil, err
    27  		}
    28  		return data, nil
    29  	}
    30  	if block.Type != "SM4 KEY" {
    31  		return nil, errors.New("SM4: unknown type")
    32  	}
    33  	return block.Bytes, nil
    34  }
    35  
    36  // ReadKeyFromPemFile will return SM4Key from filename that saved PEM format data.
    37  func ReadKeyFromPemFile(FileName string, pwd []byte) (SM4Key, error) {
    38  	data, err := ioutil.ReadFile(FileName)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	return ReadKeyFromPem(data, pwd)
    43  }
    44  
    45  // WriteKeyToPem will convert SM4Key to PEM format data and return it.
    46  func WriteKeyToPem(key SM4Key, pwd []byte) ([]byte, error) {
    47  	if pwd != nil {
    48  		block, err := x509.EncryptPEMBlock(rand.Reader,
    49  			"SM4 ENCRYPTED KEY", key, pwd, x509.PEMCipherAES256) //Use AES256  algorithms to encrypt SM4KEY
    50  		if err != nil {
    51  			return nil, err
    52  		}
    53  		return pem.EncodeToMemory(block), nil
    54  	} else {
    55  		block := &pem.Block{
    56  			Type:  "SM4 KEY",
    57  			Bytes: key,
    58  		}
    59  		return pem.EncodeToMemory(block), nil
    60  	}
    61  }
    62  
    63  // WriteKeyToPemFile will convert SM4Key to PEM format data, then write it
    64  // into the input filename.
    65  func WriteKeyToPemFile(FileName string, key SM4Key, pwd []byte) error {
    66  	var block *pem.Block
    67  	var err error
    68  	if pwd != nil {
    69  		block, err = x509.EncryptPEMBlock(rand.Reader,
    70  			"SM4 ENCRYPTED KEY", key, pwd, x509.PEMCipherAES256)
    71  		if err != nil {
    72  			return err
    73  		}
    74  	} else {
    75  		block = &pem.Block{
    76  			Type:  "SM4 KEY",
    77  			Bytes: key,
    78  		}
    79  	}
    80  	pemBytes := pem.EncodeToMemory(block)
    81  	err = ioutil.WriteFile(FileName, pemBytes, 0666)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	return nil
    86  }