github.com/XiaoMi/Gaea@v1.2.5/util/crypto/xaes_ecb.go (about) 1 // Copyright 2019 The Gaea Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package crypto 16 17 import ( 18 "bytes" 19 "crypto/aes" 20 "crypto/cipher" 21 "fmt" 22 ) 23 24 func pkcs5Padding(ciphertext []byte, blockSize int) []byte { 25 padding := blockSize - len(ciphertext)%blockSize 26 padtext := bytes.Repeat([]byte{byte(padding)}, padding) 27 return append(ciphertext, padtext...) 28 } 29 30 func pkcs5UnPadding(origData []byte) ([]byte, error) { 31 length := len(origData) 32 if length <= 0 { 33 return origData, nil 34 } 35 36 unpadding := int(origData[length-1]) 37 if length < unpadding { 38 err := fmt.Errorf("pkcs5UnPadding failed, invalid padding length") 39 return nil, err 40 } 41 42 return origData[:(length - unpadding)], nil 43 } 44 45 type ecbEncrypter struct { 46 b cipher.Block 47 blockSize int 48 } 49 50 // EncryptECB encrypt data in ecb mode 51 func EncryptECB(key string, data []byte) (result []byte, err error) { 52 block, err := aes.NewCipher([]byte(key)) 53 if err != nil { 54 return 55 } 56 57 dataPadding := pkcs5Padding(data, block.BlockSize()) 58 result = make([]byte, len(dataPadding)) 59 60 mode := newECBEncrypter(block) 61 err = mode.cryptBlocks(result, dataPadding) 62 if err != nil { 63 return 64 } 65 66 return 67 } 68 69 // DecryptECB decrypt data in ecb mode 70 func DecryptECB(key string, data []byte) (result []byte, err error) { 71 block, err := aes.NewCipher([]byte(key)) 72 if err != nil { 73 return 74 } 75 76 mode := newECBDecrypter(block) 77 err = mode.cryptBlocks(data, data) 78 if err != nil { 79 return 80 } 81 82 result, err = pkcs5UnPadding(data) 83 if err != nil { 84 return 85 } 86 87 return 88 } 89 90 func newECBEncrypter(b cipher.Block) (c *ecbEncrypter) { 91 c = new(ecbEncrypter) 92 c.b = b 93 c.blockSize = b.BlockSize() 94 return 95 } 96 97 func (e *ecbEncrypter) BlockSize() (size int) { 98 size = e.blockSize 99 return 100 } 101 102 func (e *ecbEncrypter) cryptBlocks(dst []byte, src []byte) (err error) { 103 if len(src)%e.blockSize != 0 { 104 err = fmt.Errorf("len(src)[%v] not full blocks, blocksize[%v]", len(src), e.blockSize) 105 return 106 } 107 108 if len(dst) < len(src) { 109 err = fmt.Errorf("output[%v] is smaller than input[%v]", len(dst), len(src)) 110 return 111 } 112 113 for len(src) > 0 { 114 e.b.Encrypt(dst, src[:e.blockSize]) 115 src = src[e.blockSize:] 116 dst = dst[e.blockSize:] 117 } 118 return 119 } 120 121 type ecbDecrypter struct { 122 b cipher.Block 123 blockSize int 124 } 125 126 func newECBDecrypter(b cipher.Block) (c *ecbDecrypter) { 127 c = new(ecbDecrypter) 128 c.b = b 129 c.blockSize = b.BlockSize() 130 return 131 } 132 133 func (e *ecbDecrypter) BlockSize() (size int) { 134 size = e.blockSize 135 return 136 } 137 138 func (e *ecbDecrypter) cryptBlocks(dst []byte, src []byte) (err error) { 139 if len(src)%e.blockSize != 0 { 140 err = fmt.Errorf("len(src)[%v] not full blocks, blocksize[%v]", len(src), e.blockSize) 141 return 142 } 143 if len(dst) < len(src) { 144 err = fmt.Errorf("output[%v] is smaller than input[%v]", len(dst), len(src)) 145 return 146 } 147 148 for len(src) > 0 { 149 e.b.Decrypt(dst, src[:e.blockSize]) // different from encrypter here. 150 src = src[e.blockSize:] 151 dst = dst[e.blockSize:] 152 } 153 154 return 155 }