package tdesx import ( "bytes" "crypto/cipher" "crypto/des" "crypto/rand" "encoding/hex" "errors" "fmt" "io" "strings" ) // 3DES-ECB 加密,返回大写的十六进制字符串 func EncryptECBHex(input, key string) (string, error) { // 创建3DES加密器 block, err := des.NewTripleDESCipher([]byte(key)) if err != nil { return "", err } // 对输入数据进行PKCS7填充 paddedInput := PKCS7Padding([]byte(input), block.BlockSize()) // ECB模式加密 encrypted := make([]byte, len(paddedInput)) for i := 0; i < len(paddedInput); i += des.BlockSize { block.Encrypt(encrypted[i:i+des.BlockSize], paddedInput[i:i+des.BlockSize]) } // 转换为十六进制并大写 result := hex.EncodeToString(encrypted) return strings.ToUpper(result), nil } // 3DES-ECB 解密,输入大写的十六进制字符串 func DecryptECBHex(encryptedHex, key string) (string, error) { encrypted, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } block, err := des.NewTripleDESCipher([]byte(key)) if err != nil { return "", fmt.Errorf("创建3DES解密器失败: %v", err) } // ECB模式解密 decrypted := make([]byte, len(encrypted)) for i := 0; i < len(encrypted); i += des.BlockSize { block.Decrypt(decrypted[i:i+des.BlockSize], encrypted[i:i+des.BlockSize]) } // 去除PKCS7填充 unpaddedData, err := PKCS7UnPadding(decrypted) if err != nil { return "", fmt.Errorf("去除填充失败: %v", err) } return string(unpaddedData), nil } // 3DES-CBC 加密 func EncryptCBCHex(plaintext, key string) (string, error) { block, err := des.NewTripleDESCipher([]byte(key)) if err != nil { return "", err } blockSize := block.BlockSize() plainBytes := PKCS7Padding([]byte(plaintext), blockSize) // 创建密文字节切片,包含IV空间 cipherbyte := make([]byte, des.BlockSize+len(plainBytes)) // 生成随机IV iv := cipherbyte[:des.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } // 创建CBC模式加密器 blockMode := cipher.NewCBCEncrypter(block, iv) // 加密数据 blockMode.CryptBlocks(cipherbyte[des.BlockSize:], plainBytes) // 转换为十六进制并大写 result := hex.EncodeToString(cipherbyte) return strings.ToUpper(result), nil } // 3DES-CBC 解密 func DecryptCBCHex(encryptedHex, key string) (string, error) { cipherbyte, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } if len(cipherbyte) < des.BlockSize { return "", errors.New("ciphertext too short") } block, err := des.NewTripleDESCipher([]byte(key)) if err != nil { return "", err } iv := cipherbyte[:des.BlockSize] cipherbyte = cipherbyte[des.BlockSize:] if len(cipherbyte)%des.BlockSize != 0 { return "", errors.New("ciphertext is not a multiple of the block size") } blockMode := cipher.NewCBCDecrypter(block, iv) origData := make([]byte, len(cipherbyte)) blockMode.CryptBlocks(origData, cipherbyte) origBy, err := PKCS7UnPadding(origData) if err != nil { return "", err } return string(origBy), nil } // 3DES-CFB 加密 func EncryptCFBHex(plaintext, key string) (string, error) { block, err := des.NewTripleDESCipher([]byte(key)) if err != nil { return "", err } // 创建密文字节切片,包含IV空间 cipherbyte := make([]byte, des.BlockSize+len(plaintext)) // 生成随机IV iv := cipherbyte[:des.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } // 创建CFB模式加密器 stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(cipherbyte[des.BlockSize:], []byte(plaintext)) // 转换为十六进制并大写 result := hex.EncodeToString(cipherbyte) return strings.ToUpper(result), nil } // 3DES-CFB 解密 func DecryptCFBHex(encryptedHex, key string) (string, error) { cipherbyte, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } if len(cipherbyte) < des.BlockSize { return "", errors.New("ciphertext too short") } block, err := des.NewTripleDESCipher([]byte(key)) if err != nil { return "", err } // 获取IV iv := cipherbyte[:des.BlockSize] cipherbyte = cipherbyte[des.BlockSize:] // 创建CFB模式解密器 stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(cipherbyte, cipherbyte) return string(cipherbyte), nil } // PKCS7补码 func PKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } // 去除PKCS7补码 func PKCS7UnPadding(data []byte) ([]byte, error) { length := len(data) if length == 0 { return nil, errors.New("ciphertext is empty") } unpadding := int(data[length-1]) if unpadding > length || unpadding == 0 { return nil, errors.New("unpadding size is invalid") } // 检查填充是否正确 for i := length - unpadding; i < length; i++ { if data[i] != byte(unpadding) { return nil, errors.New("invalid padding") } } return data[:(length - unpadding)], nil }