// DES、3DES加解密示例, package crypter import ( "bytes" "crypto/cipher" "crypto/des" "encoding/base64" "encoding/hex" "errors" "log" "strings" ) const KEYS = "gfe023u_sefiel#fi32lf3z!" //必须24位 /** * 加密并转换为base64字符串 */ func DesEncrypt(args ...string) (string, error) { //origData, key []byte code, keyorg, err := getArgs(args) if err != nil { return "", err } key := keyorg[0:8] block, err := des.NewCipher(key) if err != nil { return "", err } origData := []byte(code) origData = PKCS5Padding(origData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key) crypted := make([]byte, len(origData)) // 根据CryptBlocks方法的说明,如下方式初始化crypted也可以 // crypted := origData blockMode.CryptBlocks(crypted, origData) encode := base64.StdEncoding.EncodeToString(crypted) return encode, nil } /** * 加密并转换为16进制字符串 */ func DesEn(code, key string) string { block, err := des.NewCipher([]byte(key)) if err != nil { return "" } origData := []byte(code) origData = PKCS5Padding(origData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, []byte(key)) crypted := make([]byte, len(origData)) // 根据CryptBlocks方法的说明,如下方式初始化crypted也可以 // crypted := origData blockMode.CryptBlocks(crypted, origData) return strings.ToUpper(hex.EncodeToString(crypted)) } /** * 解密已转为base64字符串有DES加密 */ func DesDecrypt(args ...string) (string, error) { decode, keyorg, err := getArgs(args) if err != nil { return "", err } key := keyorg[0:8] crypted, err := base64.StdEncoding.DecodeString(decode) block, err := des.NewCipher([]byte(key)) if err != nil { return "", err } blockMode := cipher.NewCBCDecrypter(block, key) if len(crypted)%blockMode.BlockSize() != 0 { return "", errors.New("error,input not full blocks") } origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = PKCS5UnPadding(origData) return string(origData), nil } /** * 解密已转为16进制字符串有DES加密 */ func DesDe(code, key string) string { crypted, err := hex.DecodeString(code) if err != nil { return "" } block, err := des.NewCipher([]byte(key)) if err != nil { return "" } blockMode := cipher.NewCBCDecrypter(block, []byte(key)) if len(crypted)%blockMode.BlockSize() != 0 { return "" } origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = PKCS5UnPadding(origData) return string(origData) } // 3DES加密, 可与php MCRYPT_3DES加密方式对应 func TripleDesEncrypt(args ...string) (string, error) { code, key, err := getArgs(args) if err != nil { return "", err } if code == "" { return "", errors.New("加密数据为空") } block, err := des.NewTripleDESCipher(key) if err != nil { return "", err } origData := []byte(code) origData = PKCS5Padding(origData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key[:8]) crypted := make([]byte, len(origData)) blockMode.CryptBlocks(crypted, origData) encode := base64.StdEncoding.EncodeToString(crypted) return encode, nil } // 3DES解密 func TripleDesDecrypt(args ...string) (string, error) { decode, key, err := getArgs(args) if err != nil { return "", err } if decode == "" { return "", errors.New("解密数据为空") } block, err := des.NewTripleDESCipher(key) if err != nil { return "", err } crypted, decodeErr := base64.StdEncoding.DecodeString(decode) if decodeErr != nil { return "", decodeErr } blockMode := cipher.NewCBCDecrypter(block, key[:8]) origData := make([]byte, len(crypted)) if len(crypted)%blockMode.BlockSize() != 0 { log.Println("ERROR", "TripleDesDecrypt: input not full blocks") return "", errors.New("解密失败") } blockMode.CryptBlocks(origData, crypted) origData = PKCS5UnPadding(origData) return string(origData), nil } //获取参数 func getArgs(args []string) (string, []byte, error) { if len(args) == 0 { return "", nil, errors.New("参数不能为空") } origData := args[0] var crypt_key string if len(args) == 2 { crypt_key = args[1] } else { crypt_key = KEYS } key := []byte(crypt_key) return origData, key, nil } func ZeroPadding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{0}, padding) return append(ciphertext, padtext...) } func ZeroUnPadding(origData []byte) []byte { return bytes.TrimRightFunc(origData, func(r rune) bool { return r == rune(0) }) } func PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS5UnPadding(origData []byte) []byte { length := len(origData) // 去掉最后一个字节 unpadding 次 unpadding := int(origData[length-1]) if length < unpadding || unpadding/8 > 3 { //解密的是错误的数据情况下,是没有填充的 return []byte("") } return origData[:(length - unpadding)] }