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
})
}
输出结果: