gitee.com/lh-her-team/common@v1.5.1/opencrypto/gmssl/sm4/sm4.go (about) 1 package sm4 2 3 import ( 4 "crypto/rand" 5 "encoding/hex" 6 "fmt" 7 8 "gitee.com/lh-her-team/common/opencrypto/gmssl/gmssl" 9 10 "gitee.com/lh-her-team/common/opencrypto/utils" 11 12 "gitee.com/lh-her-team/common/crypto" 13 "gitee.com/lh-her-team/common/crypto/sym/modes" 14 ) 15 16 var defaultSM4Opts = &crypto.EncOpts{ 17 EncodingType: modes.PADDING_PKCS5, 18 BlockMode: modes.BLOCK_MODE_CBC, 19 EnableMAC: true, 20 Hash: 0, 21 Label: nil, 22 EnableASN1: false, 23 } 24 25 var _ crypto.SymmetricKey = (*SM4Key)(nil) 26 27 type SM4Key struct { 28 Key []byte 29 } 30 31 func (s SM4Key) Bytes() ([]byte, error) { 32 return s.Key, nil 33 } 34 35 func (s SM4Key) Type() crypto.KeyType { 36 return crypto.SM4 37 } 38 39 func (s SM4Key) String() (string, error) { 40 return hex.EncodeToString(s.Key), nil 41 } 42 43 func (s SM4Key) Encrypt(plain []byte) ([]byte, error) { 44 return s.EncryptWithOpts(plain, defaultSM4Opts) 45 } 46 47 func (s SM4Key) EncryptWithOpts(plain []byte, opts *crypto.EncOpts) ([]byte, error) { 48 switch opts.BlockMode { 49 case modes.BLOCK_MODE_CBC: 50 var iv [16]byte 51 if _, err := rand.Read(iv[:]); err != nil { 52 return nil, err 53 } 54 switch opts.EncodingType { 55 case modes.PADDING_PKCS5: 56 encrypter, err := gmssl.NewCipherContext("SMS4", s.Key, iv[:], true) 57 if err != nil { 58 return nil, err 59 } 60 cipher1, err := encrypter.Update(plain) 61 if err != nil { 62 return nil, err 63 } 64 cipher2, err := encrypter.Final() 65 if err != nil { 66 return nil, err 67 } 68 ciphertext := make([]byte, 0, len(cipher1)+len(cipher2)) 69 ciphertext = append(append(ciphertext, cipher1...), cipher2...) 70 return append(iv[:], ciphertext...), nil 71 default: 72 return nil, fmt.Errorf("SM4 encryption fails, unknown encoding type [%s]", opts.EncodingType) 73 } 74 default: 75 return nil, fmt.Errorf("SM4 encryption fails: unknown cipher block mode [%s]", opts.BlockMode) 76 } 77 } 78 79 func (s SM4Key) Decrypt(ciphertext []byte) ([]byte, error) { 80 return s.DecryptWithOpts(ciphertext, defaultSM4Opts) 81 } 82 83 func (s SM4Key) DecryptWithOpts(ciphertext []byte, opts *crypto.EncOpts) ([]byte, error) { 84 switch opts.BlockMode { 85 case modes.BLOCK_MODE_CBC: 86 if len(ciphertext) < utils.SM4_BlockSize { 87 return nil, fmt.Errorf("invalid ciphertext length, want > 16, got %d", len(ciphertext)) 88 } 89 switch opts.EncodingType { 90 case modes.PADDING_PKCS5: 91 decrypter, err := gmssl.NewCipherContext("SMS4", s.Key, ciphertext[:utils.SM4_BlockSize], false) 92 if err != nil { 93 return nil, err 94 } 95 plain1, err := decrypter.Update(ciphertext[utils.SM4_BlockSize:]) 96 if err != nil { 97 return nil, err 98 } 99 plain2, err := decrypter.Final() 100 if err != nil { 101 return nil, err 102 } 103 plain := make([]byte, 0, len(plain1)+len(plain2)) 104 plain = append(append(plain, plain1...), plain2...) 105 return plain, nil 106 default: 107 return nil, fmt.Errorf("SM4 encryption fails, unknown encoding type [%s]", opts.EncodingType) 108 } 109 default: 110 return nil, fmt.Errorf("SM4 encryption fails: unknown cipher block mode [%s]", opts.BlockMode) 111 } 112 }