88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
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
|
|
}
|