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 }