go語言 實現對稱加密解密算法


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
	})
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM