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 }