69 lines
2.3 KiB
Go
69 lines
2.3 KiB
Go
// 提供DES-CBC加密解密功能。
|
||
package des
|
||
|
||
import (
|
||
"crypto/cipher"
|
||
"crypto/des"
|
||
"crypto/sha256"
|
||
"fmt"
|
||
|
||
"archgrid.xyz/ag/toolsbox/encryption"
|
||
)
|
||
|
||
type KeyGenerator func([]byte) [8]byte
|
||
|
||
// 截取所提供的密钥进行Sha256散列以后的前8个字节作为加密密钥。
|
||
func PrefixKeyGenerator(key []byte) [8]byte {
|
||
hashKey := sha256.Sum256(key)
|
||
return ([8]byte)(hashKey[:8])
|
||
}
|
||
|
||
// 对所提供的密钥进行Sha256散列后,将散列值的前8个字节连续与后几个单元中对应的字节进行异或运算,最终得到的长度为8个字节的字节数组作为加密密钥。
|
||
func XorKeyGenerator(key []byte) [8]byte {
|
||
hashKey := sha256.Sum256(key)
|
||
var compressedKey [8]byte
|
||
for i := 0; i < 8; i++ {
|
||
for j := 0; j < 4; j++ {
|
||
compressedKey[i] ^= hashKey[i+j*8]
|
||
}
|
||
}
|
||
return compressedKey
|
||
}
|
||
|
||
// 对给定的数据进行加密。
|
||
// DES加密IV为8字节,默认与运算后的密钥相同。
|
||
// 参数padding指定了填充方式,可选值为NoPadding、ZeroPadding和PKCS7Padding,默认采用ZeroPadding。
|
||
func Encrypt(data []byte, key []byte, padding encryption.PaddingMode, keyGenerator ...KeyGenerator) ([]byte, error) {
|
||
keyBytes := append(keyGenerator, XorKeyGenerator)[0](key)
|
||
block, err := des.NewCipher(keyBytes[:])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建加密单元失败,%w", err)
|
||
}
|
||
|
||
iv := keyBytes[:]
|
||
plainText := encryption.Padding(data, block.BlockSize(), padding)
|
||
cipherText := make([]byte, len(plainText))
|
||
mode := cipher.NewCBCEncrypter(block, iv)
|
||
mode.CryptBlocks(cipherText, plainText)
|
||
|
||
return cipherText, nil
|
||
}
|
||
|
||
// 对给定的数据进行解密。
|
||
// DES解密IV为8字节,默认与运算后的密钥相同。
|
||
// 参数padding指定了填充方式,可选值为NoPadding、ZeroPadding和PKCS7Padding,默认采用ZeroPadding。
|
||
func Decrypt(data []byte, key []byte, padding encryption.PaddingMode, keyGenerator ...KeyGenerator) ([]byte, error) {
|
||
keyBytes := append(keyGenerator, XorKeyGenerator)[0](key)
|
||
block, err := des.NewCipher(keyBytes[:])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建加密单元失败,%w", err)
|
||
}
|
||
|
||
iv := keyBytes[:]
|
||
plainText := make([]byte, len(data))
|
||
mode := cipher.NewCBCDecrypter(block, iv)
|
||
mode.CryptBlocks(plainText, data)
|
||
|
||
return encryption.Unpadding(plainText, padding), nil
|
||
}
|