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

     1  package des
     2  
     3  import (
     4  	"crypto/cipher"
     5  	"crypto/des"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"strings"
     9  )
    10  
    11  // Encrypt DES加密
    12  // input 要加密的字符串	skey 加密使用的秘钥[字符串长度必须是8的倍数]
    13  func Encrypt(input string, skey string, mode string) (r string, err error) {
    14  	origData := []byte(input)
    15  	iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
    16  	crypted, err := EncryptBytes(origData, skey, iv, mode)
    17  	if err != nil {
    18  		return
    19  	}
    20  	r = strings.ToUpper(hex.EncodeToString(crypted))
    21  	return
    22  }
    23  
    24  // Decrypt DES解密
    25  // input 要解密的字符串	skey 加密使用的秘钥[字符串长度必须是8的倍数]
    26  func Decrypt(input string, skey string, mode string) (r string, err error) {
    27  	crypted, err := hex.DecodeString(input)
    28  	if err != nil {
    29  		return "", fmt.Errorf("hex DecodeString err:%v", err)
    30  	}
    31  	iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
    32  	origData, err := DecryptBytes(crypted, skey, iv, mode)
    33  	if err != nil {
    34  		return
    35  	}
    36  	r = string(origData)
    37  	return
    38  }
    39  
    40  // EncryptBytes DES加密
    41  // input 要加密的字符串	skey 加密使用的秘钥[字符串长度必须是8的倍数]
    42  func EncryptBytes(origData []byte, skey string, iv []byte, mode string) (crypted []byte, err error) {
    43  	key := []byte(skey)
    44  	block, err := des.NewCipher(key)
    45  	if err != nil {
    46  		err = fmt.Errorf("des NewCipher err:%v", err)
    47  		return
    48  	}
    49  	m, p, err := getModePadding(mode)
    50  	if err != nil {
    51  		return
    52  	}
    53  	var blockMode cipher.BlockMode
    54  	switch m {
    55  	case "ECB":
    56  		blockMode = NewECBEncrypter(block)
    57  	case "CBC":
    58  		blockMode = cipher.NewCBCEncrypter(block, iv)
    59  	default:
    60  		err = fmt.Errorf("加密模式不支持:%s", m)
    61  		return
    62  	}
    63  	switch p {
    64  	case "PKCS5":
    65  		origData = PKCS5Padding(origData, block.BlockSize())
    66  	case "PKCS7":
    67  		origData = PKCS7Padding(origData)
    68  	case "ZERO":
    69  		origData = ZeroPadding(origData, block.BlockSize())
    70  	default:
    71  		err = fmt.Errorf("填充模式不支持:%s", p)
    72  		return
    73  	}
    74  	crypted = make([]byte, len(origData))
    75  	blockMode.CryptBlocks(crypted, origData)
    76  	return
    77  }
    78  
    79  // DecryptBytes DES解密
    80  // input 要解密的字符串	skey 加密使用的秘钥[字符串长度必须是8的倍数]
    81  func DecryptBytes(crypted []byte, skey string, iv []byte, mode string) (r []byte, err error) {
    82  
    83  	key := []byte(skey)
    84  	block, err := des.NewCipher(key)
    85  	if err != nil {
    86  		err = fmt.Errorf("des NewCipher err:%v", err)
    87  		return
    88  	}
    89  	m, p, err := getModePadding(mode)
    90  	if err != nil {
    91  		return
    92  	}
    93  	var blockMode cipher.BlockMode
    94  	switch m {
    95  	case "CBC":
    96  		blockMode = cipher.NewCBCDecrypter(block, iv)
    97  	case "ECB":
    98  		blockMode = NewECBDecrypter(block)
    99  	default:
   100  		err = fmt.Errorf("加密模式不支持:%s", m)
   101  		return
   102  	}
   103  	r = make([]byte, len(crypted))
   104  	blockMode.CryptBlocks(r, crypted)
   105  	switch p {
   106  	case "PKCS5":
   107  		r = PKCS5UnPadding(r)
   108  	case "PKCS7":
   109  		r = PKCS7UnPadding(r)
   110  	case "ZERO":
   111  		r = ZeroUnPadding(r)
   112  	default:
   113  		err = fmt.Errorf("填充模式不支持:%s", p)
   114  		return
   115  	}
   116  
   117  	return
   118  }
   119  
   120  func getModePadding(name string) (mode, padding string, err error) {
   121  	names := strings.Split(name, "/")
   122  	if len(names) != 2 {
   123  		err = fmt.Errorf("输入模式不正确:%s", name)
   124  		return
   125  	}
   126  	mode = strings.ToUpper(names[0])
   127  	padding = strings.ToUpper(names[1])
   128  	if mode != "CBC" && mode != "ECB" {
   129  		err = fmt.Errorf("加密模式不支持:%s", mode)
   130  		return
   131  	}
   132  	if padding != "PKCS5" && padding != "PKCS7" && padding != "ZERO" {
   133  		err = fmt.Errorf("填充模式不支持:%s", padding)
   134  		return
   135  	}
   136  	return
   137  }