GO实现对称加密DES/3DES/AES

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/des"
	"encoding/base64"
	"fmt"
)

func main()  {
	//DES密钥

	//DES
	key := "12345678"

	//3DES
	//key := "abcdefgh0123456712345678"

	//AES
	//key = "012345678abcdefh"
	keyBytes := []byte(key)
	str := "Oneck"
	cipherArr,err := SCEncrpty([]byte(str),keyBytes,"des")
	if err != nil {
		panic(err)
	}
	fmt.Printf("加密后的字节数组%v\n",cipherArr)
	fmt.Printf("加密后16进制%x\n",cipherArr)

	originalBytes,err := SCDecrypt(cipherArr,keyBytes,"des")
	if err != nil {
		panic(nil)
	}
	fmt.Println("解密后:",string(originalBytes))
	fmt.Println("\n---------------加密解密字符串")
	str = "happy new year"
	fmt.Println("原始字符串",str)
	cipherText,err := SCEncryptString(str,key,"des")
	if err != nil {
		panic(err)
	}
	fmt.Println("解密且base64编码后",cipherText)

	originalText,err :=SCDecryptString(cipherText,key,"des")
	if err != nil {
		panic(err)
	}
	fmt.Println("解密后",originalText)
}
//字符串对称加密
func SCEncryptString(originalText,key,scType string)(string,error){
	cipherBytes,err :=SCEncrpty([]byte(originalText),[]byte(key),scType)
	if err != nil {
		return "",err
	}
	base64str :=base64.StdEncoding.EncodeToString(cipherBytes)
	return base64str,nil
}

//字符串对称解密
func SCDecryptString(cipherText,key,scType string)(string,error)  {
	cipherBytes,_ := base64.StdEncoding.DecodeString(cipherText)
	cipherBytes,err := SCDecrypt(cipherBytes,[]byte(key),scType)
	if err != nil {
		return "",err
	}
	return string(cipherBytes),nil
}
//对称加密算法
func SCEncrpty(originalBytes,key []byte,scType string) ([]byte,error) {
	//1.实例化密码器block(参数为key)
	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)

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

//解密字节切片,返回字节切片
func SCDecrypt(cipherBytes,key []byte,scType string)([]byte,error)  {
	//1.实例化密码器block(参数为key)
	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])

	//3.对密文进行解密
	paddingbytes := make([]byte,len(cipherBytes))
	blockMode.CryptBlocks(paddingbytes,cipherBytes)
	fmt.Println("解密后带有填充的字节切片",paddingbytes)
	//4.去除填充的字节
	originalBytes := PKCSSUnPadding(paddingbytes)
	return originalBytes,nil
}
//填充字节
func PKCSSpadding(data []byte,blockSize int)[]byte {
	padding := blockSize - len(data) % blockSize
	fmt.Println("要填充的字节",padding)
	slice := []byte{byte(padding)}
	slice1 := bytes.Repeat(slice,padding)
	return append(data,slice1...)
}

func ZeroPadding(data []byte,blockSize int)[]byte  {
	padding := blockSize - len(data) % blockSize
	fmt.Println("要填充的字节",padding)
	slice := []byte{byte(9)}
	slice1 := bytes.Repeat(slice,padding)
	return append(data,slice1...)
}

//去除填充字节
func PKCSSUnPadding(data []byte)[]byte  {
	unpadding := data[len(data)-1]
	result := data[:(len(data) - int(unpadding))]
	return result
}

func ZeroUnpadding(data []byte)[]byte  {
	return bytes.TrimRightFunc(data, func(r rune)bool {
		return r==0
	})
}

输出结果:
在这里插入图片描述

发布了19 篇原创文章 · 获赞 85 · 访问量 1334

猜你喜欢

转载自blog.csdn.net/qq_45828877/article/details/103950467