github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/security/triple_des/triple_des.go (about)

     1  package tripleDes
     2  
     3  import (
     4  	"crypto/cipher"
     5  	"crypto/des"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"strings"
     9  
    10  	xdes "github.com/sereiner/library/security/des"
    11  )
    12  
    13  //Encrypt 3des加密cbs/pkcs5
    14  func Encrypt(input string, skey string, mode string) (r string, err error) {
    15  	secMode, padding, err := getModes(mode)
    16  	if err != nil {
    17  		return
    18  	}
    19  	origData := []byte(input)
    20  	key := []byte(skey)
    21  	block, err := des.NewTripleDESCipher(key)
    22  	if err != nil {
    23  		return "", fmt.Errorf("des NewTripleDESCipher err:%v", err)
    24  	}
    25  
    26  	switch padding {
    27  	case "pkcs5":
    28  		origData = xdes.PKCS5Padding(origData, block.BlockSize())
    29  	case "pkcs7":
    30  		origData = xdes.PKCS7Padding(origData)
    31  	case "zero":
    32  		origData = xdes.ZeroPadding(origData, block.BlockSize())
    33  	default:
    34  		err = fmt.Errorf("不支持的填充模式:%s", padding)
    35  		return
    36  	}
    37  
    38  	switch secMode {
    39  	case "cbc":
    40  		iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
    41  		blockMode := cipher.NewCBCEncrypter(block, iv)
    42  		crypted := make([]byte, len(origData))
    43  		blockMode.CryptBlocks(crypted, origData)
    44  		r = strings.ToUpper(hex.EncodeToString(crypted))
    45  		return
    46  	case "ecb":
    47  		blockMode := xdes.NewECBEncrypter(block)
    48  		crypted := make([]byte, len(origData))
    49  		blockMode.CryptBlocks(crypted, origData)
    50  		r = strings.ToUpper(hex.EncodeToString(crypted))
    51  		return
    52  	case "cfb":
    53  		iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
    54  		blockMode := cipher.NewCFBEncrypter(block, iv)
    55  		crypted := make([]byte, len(origData))
    56  		blockMode.XORKeyStream(crypted, origData)
    57  		r = strings.ToUpper(hex.EncodeToString(crypted))
    58  		return
    59  	default:
    60  		err = fmt.Errorf("不支持的加密模式:%s", secMode)
    61  		return
    62  
    63  	}
    64  }
    65  
    66  //Decrypt 3des解密cbs/pkcs5
    67  func Decrypt(input string, skey string, mode string) (r string, err error) {
    68  	secMode, padding, err := getModes(mode)
    69  	if err != nil {
    70  		return
    71  	}
    72  	crypted, err := hex.DecodeString(input)
    73  	if err != nil {
    74  		return "", fmt.Errorf("des DecodeString err:%v", err)
    75  	}
    76  	key := []byte(skey)[:24]
    77  	block, err := des.NewTripleDESCipher(key)
    78  	if err != nil {
    79  		return "", fmt.Errorf("des NewTripleDESCipher err:%v", err)
    80  	}
    81  	origData := make([]byte, len(crypted))
    82  	switch secMode {
    83  	case "cbc":
    84  		iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
    85  		blockMode := cipher.NewCBCDecrypter(block, iv)
    86  		origData := make([]byte, len(crypted))
    87  		blockMode.CryptBlocks(origData, crypted)
    88  	case "ecb":
    89  		blockMode := xdes.NewECBDecrypter(block)
    90  		blockMode.CryptBlocks(origData, crypted)
    91  	case "cfb":
    92  		iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
    93  		blockMode := cipher.NewCFBDecrypter(block, iv)
    94  		blockMode.XORKeyStream(origData, crypted)
    95  	default:
    96  		err = fmt.Errorf("不支持的加密模式:%s", secMode)
    97  		return
    98  
    99  	}
   100  
   101  	switch padding {
   102  	case "pkcs5":
   103  		origData = xdes.PKCS5UnPadding(origData)
   104  	case "pkcs7":
   105  		origData = xdes.PKCS7UnPadding(origData)
   106  	case "zero":
   107  		origData = xdes.ZeroUnPadding(origData)
   108  	default:
   109  		err = fmt.Errorf("不支持的填充模式:%s", padding)
   110  		return
   111  	}
   112  	r = string(origData)
   113  	return
   114  }
   115  func getModes(mode string) (sec string, padding string, err error) {
   116  	if len(mode) == 0 {
   117  		return "cbc", "pkcs5", nil
   118  	}
   119  	modes := strings.SplitN(mode, "/", 2)
   120  	if len(modes) != 2 {
   121  		return "", "", fmt.Errorf("输入的加解密模式不正确:%s", mode)
   122  	}
   123  	if modes[0] != "cbc" && modes[0] != "ecb" && modes[0] != "cfb" {
   124  		return "", "", fmt.Errorf("输入的加解密模式不正确:%s只支持cbs,ecb,cfb", modes[0])
   125  	}
   126  	if modes[1] != "pkcs5" && modes[1] != "pkcs7" && modes[1] != "zero" {
   127  		return "", "", fmt.Errorf("输入的填充模式不正确:%s只支持pkcs5,pkcs7,zero", modes[0])
   128  	}
   129  	return modes[0], modes[1], nil
   130  }