基于golang常用加密解码的封装

AES : 高级加密标准;AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特;

type AES interface {
	Encrypt(str, key []byte) ([]byte, error)
	Decrypt(str, key []byte) ([]byte, error)
}


DES : 数据加密标准,是一种使用密钥加密的块算法

type DES interface {
	Encrypt(str, key []byte) ([]byte, error)
	Decrypt(str, key []byte) ([]byte, error)
}


AES&DES 支持的模式: CBC 密码分组链接模式(Cipher Block Chaining (CBC))

// CBC : 密码分组链接模式(Cipher Block Chaining (CBC)) default
type cbcObj struct {
	cryptoType string
	iv []byte
}

func (cbc *cbcObj) getBlock(key []byte) (block cipher.Block, err error) {
	if cbc.cryptoType == "aes" {
		block, err = aes.NewCipher(key)
	}
	if cbc.cryptoType == "des" {
		block, err = des.NewCipher(key)
	}
	return
}

// CBC Encrypt
func (cbc *cbcObj) Encrypt(str, key []byte) ([]byte, error) {
	block, err := cbc.getBlock(key)
	if err != nil {
		Error("["+cbc.cryptoType+"-CBC] ERROR:" +err.Error())
		return []byte(""), err
	}
	blockSize := block.BlockSize()
	originData := cbc.pkcs5Padding(str, blockSize)
	blockMode := cipher.NewCBCEncrypter(block,cbc.iv)
	cryptData := make([]byte,len(originData))
	blockMode.CryptBlocks(cryptData,originData)
	P2E()
	return cryptData, nil
}

// CBC Decrypt
func (cbc *cbcObj) Decrypt(str, key []byte) ([]byte, error) {
	block, err := cbc.getBlock(key)
	if err != nil {
		Error("["+cbc.cryptoType+"-CBC] ERROR:" +err.Error())
		return []byte(""), err
	}
	blockMode := cipher.NewCBCDecrypter(block, cbc.iv)
	originStr := make([]byte,len(str))
	blockMode.CryptBlocks(originStr,str)
	P2E()
	return cbc.pkcs5UnPadding(originStr), nil
}

func (cbc *cbcObj) pkcs5Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padText...)
}

func (cbc *cbcObj) pkcs5UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadDing := int(origData[length-1])
	return origData[:(length - unpadDing)]
}


AES&DES 支持的模式: ECB 电码本模式(Electronic Codebook Book (ECB))

// ECB : 电码本模式(Electronic Codebook Book (ECB))
type ecbObj struct {
	cryptoType string
}

func (ecb *ecbObj) getBlock(key []byte) (block cipher.Block, err error) {
	if ecb.cryptoType == "aes" {
		block, err = aes.NewCipher(ecb.generateKey(key))
	}
	if ecb.cryptoType == "des" {
		block, err = des.NewCipher(key)
	}
	return
}

// ECB Encrypt
func (ecb *ecbObj) Encrypt(str, key []byte) ([]byte, error) {
	block, err := ecb.getBlock(key)
	if err != nil {
		Error("["+ecb.cryptoType+"-ECB] ERROR:" +err.Error())
		return []byte(""), err
	}
	blockSize := block.BlockSize()
	if ecb.cryptoType == "aes" {
		str = ecb.pkcs5PaddingAes(str, blockSize)
	}
	if ecb.cryptoType == "des" {
		str = ecb.pkcs5PaddingDes(str, blockSize)
	}

	//返回加密结果
	encryptData := make([]byte, len(str))
	//存储每次加密的数据
	tmpData := make([]byte, blockSize)
	//分组分块加密
	for index := 0; index < len(str); index += blockSize {
		block.Encrypt(tmpData, str[index:index+blockSize])
		copy(encryptData, tmpData)
	}
	P2E()
	return encryptData, nil
}

func (ecb *ecbObj) pkcs5PaddingDes(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func (ecb *ecbObj) pkcs5PaddingAes(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	if padding != 0 {
		ciphertext = append(ciphertext, bytes.Repeat([]byte{byte(0)}, padding)...)
	}
	return ciphertext
}

// ECB Decrypt
func (ecb *ecbObj) Decrypt(str, key []byte) ([]byte, error) {
	block, err := ecb.getBlock(key)
	if err != nil {
		Error("["+ecb.cryptoType+"-ECB] ERROR:" +err.Error())
		return []byte(""), err
	}
	blockSize := block.BlockSize()
	//返回加密结果
	decryptData := make([]byte, len(str))
	//存储每次加密的数据
	tmpData := make([]byte, blockSize)

	//分组分块加密
	for index := 0; index < len(str); index += blockSize {
		block.Decrypt(tmpData, str[index:index+blockSize])
		copy(decryptData, tmpData)
	}

	if ecb.cryptoType == "des" {
		return ecb.pkcs5UnPadding(decryptData), nil
	}
	P2E()
	return ecb.unPadding(decryptData), nil
}

func (ecb *ecbObj) generateKey(key []byte) (genKey []byte) {
	genKey = make([]byte, 16)
	copy(genKey, key)
	for i := 16; i < len(key); {
		for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
			genKey[j] ^= key[i]
		}
	}
	return genKey
}

func (ecb *ecbObj) unPadding(src []byte) []byte {
	for i := len(src) - 1; ; i-- {
		if src[i] != 0 {
			return src[:i+1]
		}
	}
}

func (ecb *ecbObj) pkcs5UnPadding(origData []byte) []byte {
	length := len(origData)
	unPadding := int(origData[length-1])
	return origData[:(length - unPadding)]
}

AES&DES 支持的模式: CFB : 密码反馈模式(Cipher FeedBack (CFB))

// 密码反馈模式(Cipher FeedBack (CFB))
type cfbObj struct {
	cryptoType string
}

func (cfb *cfbObj) getBlock(key []byte) (block cipher.Block, err error) {
	if cfb.cryptoType == "aes" {
		block, err = aes.NewCipher(key)
	}
	if cfb.cryptoType == "des" {
		block, err = des.NewCipher(key)
	}
	return
}

// CFB Encrypt
func (cfb *cfbObj) Encrypt(str, key []byte) ([]byte, error) {
	P2E()
	block, err := cfb.getBlock(key)
	if err != nil {
		Error("["+cfb.cryptoType+"-CFB] ERROR:" +err.Error())
		return nil, err
	}

	if cfb.cryptoType == "aes" {
		encrypted := make([]byte, aes.BlockSize+len(str))
		iv := encrypted[:aes.BlockSize]
		if _, err := io.ReadFull(rand.Reader, iv); err != nil {
			return nil, err
		}
		stream := cipher.NewCFBEncrypter(block, iv)
		stream.XORKeyStream(encrypted[aes.BlockSize:], str)
		return encrypted, nil
	}

	if cfb.cryptoType == "des" {
		encrypted := make([]byte, des.BlockSize+len(str))
		iv := encrypted[:des.BlockSize]
		if _, err := io.ReadFull(rand.Reader, iv); err != nil {
			return nil, err
		}
		stream := cipher.NewCFBEncrypter(block, iv)
		stream.XORKeyStream(encrypted[des.BlockSize:], str)
		return encrypted, nil
	}
	return nil, nil
}

// CFB Decrypt
func (cfb *cfbObj) Decrypt(str, key []byte) ([]byte, error) {
	P2E()
	block, err := cfb.getBlock(key)
	if err != nil {
		Error("["+cfb.cryptoType+"-CFB] ERROR:" +err.Error())
		return nil, err
	}

	iv := []byte{}
	if cfb.cryptoType == "aes" {
		if len(str) < aes.BlockSize {
			return nil, errors.New("ciphertext too short")
		}
		iv = str[:aes.BlockSize]
		str = str[aes.BlockSize:]
	}

	if cfb.cryptoType == "des" {
		if len(str) < des.BlockSize {
			return nil, errors.New("ciphertext too short")
		}
		iv = str[:des.BlockSize]
		str = str[des.BlockSize:]
	}

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(str, str)
	return str, nil
}

AES&DES 支持的模式: CTR 计算器模式(Counter (CTR))

// 计算器模式(Counter (CTR))
type ctrObj struct {
	count []byte //指定计数器,长度必须等于block的块尺寸
	cryptoType string
}

func (ctr *ctrObj) getBlock(key []byte) (block cipher.Block, err error) {
	if ctr.cryptoType == "aes" {
		block, err = aes.NewCipher(key)
	}
	if ctr.cryptoType == "des" {
		block, err = des.NewCipher(key)
		if len(ctr.count) > des.BlockSize {
			ctr.count = ctr.count[0:des.BlockSize]
		}
	}
	return
}

// CTR Encrypt
func (ctr *ctrObj) Encrypt(str, key []byte) ([]byte, error) {
	return ctr.crypto(str, key)
}

// CTR Decrypt
func (ctr *ctrObj) Decrypt(str, key []byte) ([]byte, error) {
	return ctr.crypto(str, key)
}

func (ctr *ctrObj) crypto(str, key []byte) ([]byte, error) {
	P2E()
	block,err:=ctr.getBlock(key)
	if err != nil {
		Error("[AES-CTR] ERROR:" +err.Error())
		return []byte(""), err
	}
	//指定分组模式
	blockMode:=cipher.NewCTR(block, ctr.count)
	//执行加密、解密操作
	res:=make([]byte,len(str))
	blockMode.XORKeyStream(res,str)
	//返回明文或密文
	return res, nil
}

AES&DES 支持的模式: OFB : 输出反馈模式(Output FeedBack (OFB))

// 输出反馈模式(Output FeedBack (OFB))
type ofbObj struct {}

Hmac 是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

func hmacFunc(h func() hash.Hash, str, key []byte) string {
	mac := hmac.New(h, key)
	mac.Write(str)
	res := base64.StdEncoding.EncodeToString(mac.Sum(nil))
	return res
}

// HmacMD5
func HmacMD5(str, key string) string {
	return hmacFunc(md5.New, []byte(str), []byte(key))
}

// HmacSHA1
func HmacSHA1(str, key string) string {
	return hmacFunc(sha1.New, []byte(str), []byte(key))
}

// HmacSHA256
func HmacSHA256(str, key string) string {
	return hmacFunc(sha256.New, []byte(str), []byte(key))
}

// HmacSHA512
func HmacSHA512(str, key string) string {
	return hmacFunc(sha512.New, []byte(str), []byte(key))
}


PBKDF2应用一个伪随机函数以导出密钥

func pbkdf2Func(h func() hash.Hash, str, salt []byte, iterations, keySize int) []byte {
	return pbkdf2.Key(str, salt, iterations, keySize, h)
}

// PBKDF2
func PBKDF2(str, salt []byte, iterations, keySize int) ([]byte) {
	return pbkdf2Func(sha256.New, str, salt, iterations, keySize)
}

JWT: JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种简介的、自包含的协议格式,用于
在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或使用RSA的公
钥/私钥对来签名,防止被篡改。

// jwtEncrypt
func jwtEncrypt(token *jwt.Token, data map[string]interface{}, secret string) (string, error) {
	claims := make(jwt.MapClaims)
	for k, v := range data {
		claims[k] = v
	}
	token.Claims = claims
	return token.SignedString([]byte(secret))
}

// JwtEncrypt
func JwtEncrypt(data map[string]interface{}, secret, method string) (string, error){
	switch method {
	case "256":
		return jwtEncrypt(jwt.New(jwt.SigningMethodHS256), data, secret)
	case "384":
		return jwtEncrypt(jwt.New(jwt.SigningMethodHS384), data, secret)
	case "512":
		return jwtEncrypt(jwt.New(jwt.SigningMethodHS512), data, secret)
	}
	return "",fmt.Errorf("未知method; method= 256 or 384 or 512 ")
}

// JwtEncrypt256
func JwtEncrypt256(data map[string]interface{}, secret string) (string, error){
	token := jwt.New(jwt.SigningMethodHS256)
	return jwtEncrypt(token, data, secret)
}

// JwtEncrypt384
func JwtEncrypt384(data map[string]interface{}, secret string) (string, error){
	token := jwt.New(jwt.SigningMethodHS384)
	return jwtEncrypt(token, data, secret)
}

// JwtEncrypt512
func JwtEncrypt512(data map[string]interface{}, secret string) (string, error){
	token := jwt.New(jwt.SigningMethodHS512)
	return jwtEncrypt(token, data, secret)
}

// JwtDecrypt
func JwtDecrypt(tokenString, secret string) (data map[string]interface{}, err error) {
	data = make(map[string]interface{})
	var secretFunc = func() jwt.Keyfunc { //按照这样的规则解析
		return func(t *jwt.Token) (interface{}, error) {
			return []byte(secret), nil
		}
	}
	token, err := jwt.Parse(tokenString, secretFunc())
	if err != nil {
		err = fmt.Errorf("未知Token")
		return
	}
	claim, ok := token.Claims.(jwt.MapClaims)
	if !ok {
		return
	}
	if !token.Valid {
		// 令牌错误
		return
	}
	for k, v := range claim {
		data[k] =v
	}
	return
}

其它: Rabbit, RC4, RIPEMD-160, DSA, RSA

源码传送门

https://github.com/mangenotwork/gathertool/blob/main/crypto.go

转载 : http://mange.work/blog?id=28

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值