ag_toolsbox/encryption/des/des.go

69 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 提供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
}