package crypto import ( "crypto/cipher" "crypto/des" "crypto/md5" ) func NewDESCryptor(c config) *desEDE3CBC { k, iv := bytesToKey(md5.New, c.Secret(), []byte{}, 1, 24, 8) return &desEDE3CBC{ key: k, iv: iv, } } type desEDE3CBC struct { key []byte iv []byte } func (d desEDE3CBC) Encrypt(content []byte) (encrypted []byte, err error) { var block cipher.Block if block, err = des.NewTripleDESCipher(d.key); err != nil { return } cbc := cipher.NewCBCEncrypter(block, d.iv) encrypted, err = d.crypt(content, cbc) return } func (d desEDE3CBC) Decrypt(encrypted []byte) (content []byte, err error) { var block cipher.Block if block, err = des.NewTripleDESCipher(d.key); err != nil { return } cbc := cipher.NewCBCDecrypter(block, d.iv) content, err = d.crypt(encrypted, cbc) return } func (d desEDE3CBC) crypt(in []byte, cbc cipher.BlockMode) (out []byte, err error) { blockSize := cbc.BlockSize() padded := padding(in, blockSize) entriesCount := len(padded) crypted := make([][]byte, entriesCount) for i := 0; i < entriesCount; i++ { crypted[i] = make([]byte, blockSize) cbc.CryptBlocks(crypted[i], padded[i]) } contentSize := len(in) out = make([]byte, contentSize) for i := 0; i < entriesCount; i++ { for j := 0; j < blockSize; j++ { index := i*blockSize + j if index >= contentSize { break } out[index] = crypted[i][j] } } return } func padding(content []byte, blockSize int) (padded [][]byte) { contentLength := len(content) size := contentLength / blockSize if contentLength%blockSize != 0 { size++ } padded = make([][]byte, size) for i := 0; i < size; i++ { padded[i] = make([]byte, blockSize) entry := padded[i] for j := 0; j < blockSize; j++ { index := i*blockSize + j if index >= contentLength { for k := j; k < blockSize; k++ { entry[k] = 0 } break } entry[j] = content[index] } } return }