gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm4soft/utils.go (about) 1 // Copyright (c) 2022 zhaochun 2 // core-gm is licensed under Mulan PSL v2. 3 // You can use this software according to the terms and conditions of the Mulan PSL v2. 4 // You may obtain a copy of Mulan PSL v2 at: 5 // http://license.coscl.org.cn/MulanPSL2 6 // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 7 // See the Mulan PSL v2 for more details. 8 9 /* 10 sm4soft 是sm4的纯软实现,基于tjfoc国密算法库`tjfoc/gmsm`做了少量修改。 11 对应版权声明: thrid_licenses/github.com/tjfoc/gmsm/版权声明 12 */ 13 14 package sm4soft 15 16 import ( 17 "crypto/rand" 18 "encoding/pem" 19 "errors" 20 "io/ioutil" 21 22 gmx509 "gitee.com/ks-custle/core-gm/x509" 23 ) 24 25 // ReadKeyFromPem will return SM4Key from PEM format data. 26 func ReadKeyFromPem(data []byte, pwd []byte) (SM4Key, error) { 27 block, _ := pem.Decode(data) 28 if block == nil { 29 return nil, errors.New("SM4: pem decode failed") 30 } 31 if gmx509.IsEncryptedPEMBlock(block) { 32 if block.Type != "SM4 ENCRYPTED KEY" { 33 return nil, errors.New("SM4: unknown type") 34 } 35 if len(pwd) == 0 { 36 return nil, errors.New("SM4: need passwd") 37 } 38 data, err := gmx509.DecryptPEMBlock(block, pwd) 39 if err != nil { 40 return nil, err 41 } 42 return data, nil 43 } 44 if block.Type != "SM4 KEY" { 45 return nil, errors.New("SM4: unknown type") 46 } 47 return block.Bytes, nil 48 } 49 50 // ReadKeyFromPemFile will return SM4Key from filename that saved PEM format data. 51 func ReadKeyFromPemFile(FileName string, pwd []byte) (SM4Key, error) { 52 data, err := ioutil.ReadFile(FileName) 53 if err != nil { 54 return nil, err 55 } 56 return ReadKeyFromPem(data, pwd) 57 } 58 59 // WriteKeyToPem will convert SM4Key to PEM format data and return it. 60 // 61 //goland:noinspection GoUnusedExportedFunction 62 func WriteKeyToPem(key SM4Key, pwd []byte) ([]byte, error) { 63 if pwd != nil { 64 block, err := gmx509.EncryptPEMBlock(rand.Reader, 65 "SM4 ENCRYPTED KEY", key, pwd, gmx509.PEMCipherAES256) //Use AES256 algorithms to encrypt SM4KEY 66 if err != nil { 67 return nil, err 68 } 69 return pem.EncodeToMemory(block), nil 70 } else { 71 block := &pem.Block{ 72 Type: "SM4 KEY", 73 Bytes: key, 74 } 75 return pem.EncodeToMemory(block), nil 76 } 77 } 78 79 // WriteKeyToPemFile will convert SM4Key to PEM format data, then write it 80 // into the input filename. 81 func WriteKeyToPemFile(FileName string, key SM4Key, pwd []byte) error { 82 var block *pem.Block 83 var err error 84 if pwd != nil { 85 block, err = gmx509.EncryptPEMBlock(rand.Reader, 86 "SM4 ENCRYPTED KEY", key, pwd, gmx509.PEMCipherAES256) 87 if err != nil { 88 return err 89 } 90 } else { 91 block = &pem.Block{ 92 Type: "SM4 KEY", 93 Bytes: key, 94 } 95 } 96 pemBytes := pem.EncodeToMemory(block) 97 err = ioutil.WriteFile(FileName, pemBytes, 0666) 98 if err != nil { 99 return err 100 } 101 return nil 102 } 103 104 // WriteKeytoMem sm4密钥转为pem字节数组 105 // 106 //goland:noinspection GoUnusedExportedFunction 107 func WriteKeytoMem(key SM4Key, pwd []byte) ([]byte, error) { 108 if pwd != nil { 109 block, err := gmx509.EncryptPEMBlock(rand.Reader, 110 "SM4 ENCRYPTED KEY", key, pwd, gmx509.PEMCipherAES256) 111 if err != nil { 112 return nil, err 113 } 114 return pem.EncodeToMemory(block), nil 115 } else { 116 block := &pem.Block{ 117 Type: "SM4 KEY", 118 Bytes: key, 119 } 120 return pem.EncodeToMemory(block), nil 121 } 122 } 123 124 // ReadKeyFromMem 将pem字节数组转为sm4密钥 125 // 126 //goland:noinspection GoUnusedExportedFunction 127 func ReadKeyFromMem(data []byte, pwd []byte) (SM4Key, error) { 128 block, _ := pem.Decode(data) 129 if gmx509.IsEncryptedPEMBlock(block) { 130 if block.Type != "SM4 ENCRYPTED KEY" { 131 return nil, errors.New("SM4: unknown type") 132 } 133 if len(pwd) == 0 { 134 return nil, errors.New("SM4: need passwd") 135 } 136 data, err := gmx509.DecryptPEMBlock(block, pwd) 137 if err != nil { 138 return nil, err 139 } 140 return data, nil 141 } 142 if block.Type != "SM4 KEY" { 143 return nil, errors.New("SM4: unknown type") 144 } 145 return block.Bytes, nil 146 }