golang 使用 cipher、aes 实现 oauth2 验证

在Go语言中,crypto/cipher包提供了加密和解密消息的功能。这个包实现了各种加密算法,如AES、DES、3DES、RC4等,以及相应的模式,如ECB、CBC、CFB、OFB、CTR等。以下是如何使用crypto/cipher包进行加密和解密操作的基本步骤:

  1. 选择加密算法和模式

    首先,你需要选择一个加密算法和一个工作模式。例如,AES算法与CBC模式的组合是一种常用的选择。

  2. 生成密钥和初始化向量(如果需要)

    对于某些加密模式,如CBC、CFB、OFB等,你需要一个初始化向量(IV)。此外,你还需要一个密钥,它的长度取决于你选择的算法。

go 复制代码
package usecase

import (
	"bytes"
	"context"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"
	"math/rand"
)

type Oauth2UseCase struct {
	key   []byte
	block cipher.Block
}
// 实例化结构
func NewOauth2UseCase() Oauth2UseCase {
	return &Oauth2UseCase{key: []byte("x1selczyiorss9jmrxllfqhykwkw8hlp")}
}

加密数据

go 复制代码
func (u *Oauth2UseCase) aesEncrypt(orig string) (string, error) {
	// 生成随机盐值
	salt := rand.Intn(25)
	orig = orig + string(u.key[salt:salt+5])
	fmt.Println("orig", salt, orig)
	// 转成字节数组
	origData := []byte(orig)

	// 分组秘钥
	block, err := aes.NewCipher(u.key)
	if err != nil {
		return "", err
	}
	// 获取秘钥块的长度
	blockSize := block.BlockSize()
	// 补全码
	origData = PKCS7Padding(origData, blockSize)
	// 加密模式
	blockMode := cipher.NewCBCEncrypter(block, u.key[:blockSize])
	// 创建数组
	cryted := make([]byte, len(origData))
	// 加密
	blockMode.CryptBlocks(cryted, origData)
	//使用RawURLEncoding 不要使用StdEncoding
	//不要使用StdEncoding  放在url参数中回导致错误
	return base64.RawURLEncoding.EncodeToString(cryted), nil
}

解密数据

go 复制代码
func (u *Oauth2UseCase) aesDecrypt(cryted string) (string, error) {
	//使用RawURLEncoding 不要使用StdEncoding
	//不要使用StdEncoding  放在url参数中回导致错误
	crytedByte, _ := base64.RawURLEncoding.DecodeString(cryted)

	// 分组秘钥
	block, err := aes.NewCipher(u.key)
	if err != nil {
		return "", err
	}
	// 获取秘钥块的长度
	blockSize := block.BlockSize()
	// 加密模式
	blockMode := cipher.NewCBCDecrypter(block, u.key[:blockSize])
	// 创建数组
	orig := make([]byte, len(crytedByte))
	// 解密
	blockMode.CryptBlocks(orig, crytedByte)
	// 去补全码
	orig = PKCS7UnPadding(orig)
	return string(orig)[:11], nil
}

处理填充

在加密和解密过程中,你可能需要对数据进行填充和去填充。填充的目的是确保数据的大小是加密算法块大小的倍数。常见的填充方案有PKCS#7、Zero Padding等。

go 复制代码
// PKCS7Padding 补码
func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
	padding := blocksize - len(ciphertext)%blocksize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

// PKCS7UnPadding 去码
func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}

以上是使用crypto/cipher包进行基本加密和解密操作的步骤。在实际应用中,你可能需要结合其他安全实践,如使用安全的随机数生成器、管理密钥、处理错误等,以确保加密过程的安全性。此外,对于某些应用场景,你可能还需要考虑使用更高级的加密库,如crypto/nacl或golang.org/x/crypto,它们提供了更多的加密算法和更高级的安全性。

go 复制代码
// 加密数据,如手机号
code, err := u.aesEncrypt(phone)
//解密数据
phone, err := u.aesDecrypt(code)
相关推荐
点心的游戏开发世界28 分钟前
GDScript 入门笔记(十一):Lambda 与匿名函数
开发语言·笔记·游戏引擎·godot
摇滚侠33 分钟前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 使用 JdbcTemplate 阅读笔记 32
spring boot·笔记·后端
步行cgn2 小时前
@Configuration 详解:Spring 配置类的核心注解
java·后端·spring
事圆则缓2 小时前
Kotlin 协程完全指南
开发语言·kotlin
我爱写代码i3 小时前
BeLink - 支持生成多种URL 缩短网址PHP源码
开发语言·php·短网址php源码
Java后端的Ai之路3 小时前
20、Python - 备忘录模式
开发语言·人工智能·python·外观模式·备忘录模式
桦说编程3 小时前
【AtomicAgent系列1】变异测试——过去做不起,现在 agent 做得起
后端·ai编程·vibecoding
统计学小王子4 小时前
数学建模国赛倒计时4天——《统计模型精讲(混合效应模型R语言实现)》
开发语言·数学建模·r语言
知无不研4 小时前
c语言中循环的介绍与简单应用
c语言·开发语言·算法·循环·for·while
郝学胜-神的一滴4 小时前
Qt 高级编程 045:坐标体系深度实战
开发语言·c++·windows·python·qt·程序人生