github.com/zhongdalu/gf@v1.0.0/g/crypto/gdes/gdes.go (about) 1 // Copyright 2018 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 // Package gdes provides useful API for DES encryption/decryption algorithms. 8 package gdes 9 10 import ( 11 "bytes" 12 "crypto/cipher" 13 "crypto/des" 14 "errors" 15 ) 16 17 const ( 18 NOPADDING = iota 19 PKCS5PADDING 20 ) 21 22 // ECB模式DES加密 23 func DesECBEncrypt(key []byte, clearText []byte, padding int) ([]byte, error) { 24 text, err := Padding(clearText, padding) 25 if err != nil { 26 return nil, err 27 } 28 29 cipherText := make([]byte, len(text)) 30 31 block, err := des.NewCipher(key) 32 if err != nil { 33 return nil, err 34 } 35 36 blockSize := block.BlockSize() 37 for i, count := 0, len(text)/blockSize; i < count; i++ { 38 begin, end := i*blockSize, i*blockSize+blockSize 39 block.Encrypt(cipherText[begin:end], text[begin:end]) 40 } 41 return cipherText, nil 42 } 43 44 // ECB模式DES解密 45 func DesECBDecrypt(key []byte, cipherText []byte, padding int) ([]byte, error) { 46 text := make([]byte, len(cipherText)) 47 block, err := des.NewCipher(key) 48 if err != nil { 49 return nil, err 50 } 51 52 blockSize := block.BlockSize() 53 for i, count := 0, len(text)/blockSize; i < count; i++ { 54 begin, end := i*blockSize, i*blockSize+blockSize 55 block.Decrypt(text[begin:end], cipherText[begin:end]) 56 } 57 58 clearText, err := UnPadding(text, padding) 59 if err != nil { 60 return nil, err 61 } 62 return clearText, nil 63 } 64 65 // ECB模式3DES加密,密钥长度可以是16或24位长 66 func TripleDesECBEncrypt(key []byte, clearText []byte, padding int) ([]byte, error) { 67 if len(key) != 16 && len(key) != 24 { 68 return nil, errors.New("key length error") 69 } 70 71 text, err := Padding(clearText, padding) 72 if err != nil { 73 return nil, err 74 } 75 76 var newKey []byte 77 if len(key) == 16 { 78 newKey = append([]byte{}, key...) 79 newKey = append(newKey, key[:8]...) 80 } else { 81 newKey = append([]byte{}, key...) 82 } 83 84 block, err := des.NewTripleDESCipher(newKey) 85 if err != nil { 86 return nil, err 87 } 88 89 blockSize := block.BlockSize() 90 cipherText := make([]byte, len(text)) 91 for i, count := 0, len(text)/blockSize; i < count; i++ { 92 begin, end := i*blockSize, i*blockSize+blockSize 93 block.Encrypt(cipherText[begin:end], text[begin:end]) 94 } 95 return cipherText, nil 96 } 97 98 // ECB模式3DES解密,密钥长度可以是16或24位长 99 func TripleDesECBDecrypt(key []byte, cipherText []byte, padding int) ([]byte, error) { 100 if len(key) != 16 && len(key) != 24 { 101 return nil, errors.New("key length error") 102 } 103 104 var newKey []byte 105 if len(key) == 16 { 106 newKey = append([]byte{}, key...) 107 newKey = append(newKey, key[:8]...) 108 } else { 109 newKey = append([]byte{}, key...) 110 } 111 112 block, err := des.NewTripleDESCipher(newKey) 113 if err != nil { 114 return nil, err 115 } 116 117 blockSize := block.BlockSize() 118 text := make([]byte, len(cipherText)) 119 for i, count := 0, len(text)/blockSize; i < count; i++ { 120 begin, end := i*blockSize, i*blockSize+blockSize 121 block.Decrypt(text[begin:end], cipherText[begin:end]) 122 } 123 124 clearText, err := UnPadding(text, padding) 125 if err != nil { 126 return nil, err 127 } 128 return clearText, nil 129 } 130 131 // CBC模式DES加密 132 func DesCBCEncrypt(key []byte, clearText []byte, iv []byte, padding int) ([]byte, error) { 133 block, err := des.NewCipher(key) 134 if err != nil { 135 return nil, err 136 } 137 138 if len(iv) != block.BlockSize() { 139 return nil, errors.New("iv length invalid") 140 } 141 142 text, err := Padding(clearText, padding) 143 if err != nil { 144 return nil, err 145 } 146 cipherText := make([]byte, len(text)) 147 148 encrypter := cipher.NewCBCEncrypter(block, iv) 149 encrypter.CryptBlocks(cipherText, text) 150 151 return cipherText, nil 152 } 153 154 // CBC模式DES解密 155 func DesCBCDecrypt(key []byte, cipherText []byte, iv []byte, padding int) ([]byte, error) { 156 block, err := des.NewCipher(key) 157 if err != nil { 158 return nil, err 159 } 160 161 if len(iv) != block.BlockSize() { 162 return nil, errors.New("iv length invalid") 163 } 164 165 text := make([]byte, len(cipherText)) 166 decrypter := cipher.NewCBCDecrypter(block, iv) 167 decrypter.CryptBlocks(text, cipherText) 168 169 clearText, err := UnPadding(text, padding) 170 if err != nil { 171 return nil, err 172 } 173 174 return clearText, nil 175 } 176 177 // CBC模式3DES加密 178 func TripleDesCBCEncrypt(key []byte, clearText []byte, iv []byte, padding int) ([]byte, error) { 179 if len(key) != 16 && len(key) != 24 { 180 return nil, errors.New("key length invalid") 181 } 182 183 var newKey []byte 184 if len(key) == 16 { 185 newKey = append([]byte{}, key...) 186 newKey = append(newKey, key[:8]...) 187 } else { 188 newKey = append([]byte{}, key...) 189 } 190 191 block, err := des.NewTripleDESCipher(newKey) 192 if err != nil { 193 return nil, err 194 } 195 196 if len(iv) != block.BlockSize() { 197 return nil, errors.New("iv length invalid") 198 } 199 200 text, err := Padding(clearText, padding) 201 if err != nil { 202 return nil, err 203 } 204 205 cipherText := make([]byte, len(text)) 206 encrypter := cipher.NewCBCEncrypter(block, iv) 207 encrypter.CryptBlocks(cipherText, text) 208 209 return cipherText, nil 210 } 211 212 // CBC模式3DES解密 213 func TripleDesCBCDecrypt(key []byte, cipherText []byte, iv []byte, padding int) ([]byte, error) { 214 if len(key) != 16 && len(key) != 24 { 215 return nil, errors.New("key length invalid") 216 } 217 218 var newKey []byte 219 if len(key) == 16 { 220 newKey = append([]byte{}, key...) 221 newKey = append(newKey, key[:8]...) 222 } else { 223 newKey = append([]byte{}, key...) 224 } 225 226 block, err := des.NewTripleDESCipher(newKey) 227 if err != nil { 228 return nil, err 229 } 230 231 if len(iv) != block.BlockSize() { 232 return nil, errors.New("iv length invalid") 233 } 234 235 text := make([]byte, len(cipherText)) 236 decrypter := cipher.NewCBCDecrypter(block, iv) 237 decrypter.CryptBlocks(text, cipherText) 238 239 clearText, err := UnPadding(text, padding) 240 if err != nil { 241 return nil, err 242 } 243 244 return clearText, nil 245 } 246 247 // PKCS5补位 248 func PKCS5Padding(text []byte, blockSize int) []byte { 249 padding := blockSize - len(text)%blockSize 250 padtext := bytes.Repeat([]byte{byte(padding)}, padding) 251 return append(text, padtext...) 252 } 253 254 // 去除PKCS5补位 255 func PKCS5Unpadding(text []byte) []byte { 256 length := len(text) 257 padtext := int(text[length-1]) 258 return text[:(length - padtext)] 259 } 260 261 // 补位方法 262 func Padding(text []byte, padding int) ([]byte, error) { 263 switch padding { 264 case NOPADDING: 265 if len(text)%8 != 0 { 266 return nil, errors.New("text length invalid") 267 } 268 case PKCS5PADDING: 269 return PKCS5Padding(text, 8), nil 270 default: 271 return nil, errors.New("padding type error") 272 } 273 274 return text, nil 275 } 276 277 // 去除补位方法 278 func UnPadding(text []byte, padding int) ([]byte, error) { 279 switch padding { 280 case NOPADDING: 281 if len(text)%8 != 0 { 282 return nil, errors.New("text length invalid") 283 } 284 case PKCS5PADDING: 285 return PKCS5Unpadding(text), nil 286 default: 287 return nil, errors.New("padding type error.") 288 } 289 return text, nil 290 }