|
|
- // 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)]
- }
|