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 }