// 提供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[:] cipherText := make([]byte, len(data)) plainText := encryption.Padding(data, block.BlockSize(), padding) 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 }