package main import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/des" "encoding/base64" "fmt" ) // main 入口函數 func main() { // DES密鑰 key := "12345678" // 占8字節 // 3DES密鑰 // key = "abcdefgh0123456712345678" //占24字節 // AES密鑰 key長度 16 24 32 對應 AES-128 AES-192 AES-256 // key = "abcdefgh0123456712345678" //占24字節 data := "學習技術,改變世界" chipherArr, err := SCEncryptString(data, key, "des") if err != nil { panic(err) } fmt.Printf("加密后字節數組:%v\n", chipherArr) fmt.Printf("加密后16進制:%x\n", chipherArr) originalBytes, err := SCDecryptString(chipherArr, key, "des") if err != nil { panic(err) } fmt.Println("解密后:", string(originalBytes)) } // SCEncrypt DES加密 func SCEncrypt(originalBytes, key []byte, scType string) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) var err error var block cipher.Block switch scType { case "des": block, err = des.NewCipher(key) case "3des": block, err = des.NewTripleDESCipher(key) case "aes": block, err = aes.NewCipher(key) } if err != nil { return nil, err } blockSize := block.BlockSize() fmt.Println("---blockSize---", blockSize) // 2、對明文填充字節(參數為原始字節切片和密碼對象的區塊個數) paddingBytes := PKCSSPadding(originalBytes, blockSize) fmt.Println("填充后的字節切片:", paddingBytes) // 3、 實例化加密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) fmt.Println("加密模式:", blockMode) // 4、對填充字節后的明文進行加密(參數為加密字節切片和填充字節切片) cipherBytes := make([]byte, len(paddingBytes)) blockMode.CryptBlocks(cipherBytes, paddingBytes) return cipherBytes, nil } // SCDecrypt 解密字節切片,返回字節切片 func SCDecrypt(cipherBytes, key []byte, scType string) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) var err error var block cipher.Block switch scType { case "des": block, err = des.NewCipher(key) case "3des": block, err = des.NewTripleDESCipher(key) case "aes": block, err = aes.NewCipher(key) } if err != nil { return nil, err } blockSize := block.BlockSize() // 2、 實例化解密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // fmt.Println("解密模式:", blockMode) // 3、對密文進行解密(參數為加密字節切片和填充字節切片) paddingBytes := make([]byte, len(cipherBytes)) blockMode.CryptBlocks(paddingBytes, cipherBytes) // 4、去除填充字節(參數為填充切片) originalBytes := PKCSSUnPadding(paddingBytes) return originalBytes, nil } // SCEncryptString SCEncryptString func SCEncryptString(originalText, key, scType string) (string, error) { chipherArr, err := SCEncrypt([]byte(originalText), []byte(key), scType) if err != nil { panic(err) } base64str := base64.StdEncoding.EncodeToString(chipherArr) return base64str, nil } // SCDecryptString SCDecryptString func SCDecryptString(chipherText, key, scType string) (string, error) { chipherArr, _ := base64.StdEncoding.DecodeString(chipherText) chipherArr, err := SCDecrypt(chipherArr, []byte(key), scType) if err != nil { panic(err) } return string(chipherArr), nil } // PKCSSPadding 填充字節的函數 func PKCSSPadding(data []byte, blockSize int) []byte { padding := blockSize - len(data)%blockSize fmt.Println("要填充的字節:", padding) // 初始化一個元素為padding的切片 slice1 := []byte{byte(padding)} slice2 := bytes.Repeat(slice1, padding) return append(data, slice2...) } // ZeroPadding 填充字節的函數 func ZeroPadding(data []byte, blockSize int) []byte { padding := blockSize - len(data)%blockSize fmt.Println("要填充的字節:", padding) // 初始化一個元素為padding的切片 slice1 := []byte{0} slice2 := bytes.Repeat(slice1, padding) return append(data, slice2...) } // PKCSSUnPadding 去除填充字節的函數 func PKCSSUnPadding(data []byte) []byte { unpadding := data[len(data)-1] result := data[:(len(data) - int(unpadding))] return result } // ZeroUnPadding 去除填充字節的函數 func ZeroUnPadding(data []byte) []byte { return bytes.TrimRightFunc(data, func(r rune) bool { return r == 0 }) }