完成所有的加密和加密链接
This commit is contained in:
parent
3be161a011
commit
66808fc735
|
@ -60,6 +60,7 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
|
||||||
// 确认email 重新序列化
|
// 确认email 重新序列化
|
||||||
token.Email = req.Email
|
token.Email = req.Email
|
||||||
token.WCId = req.WCId
|
token.WCId = req.WCId
|
||||||
|
token.GuestId = req.GuestId
|
||||||
|
|
||||||
clurl, err := l.svcCtx.TokenManger.Generate(token)
|
clurl, err := l.svcCtx.TokenManger.Generate(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -91,6 +91,7 @@ func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, us
|
||||||
log.Println(r.Json())
|
log.Println(r.Json())
|
||||||
|
|
||||||
googleId := r.Json().Get("id").Int()
|
googleId := r.Json().Get("id").Int()
|
||||||
|
|
||||||
user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId)
|
user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != gorm.ErrRecordNotFound {
|
if err != gorm.ErrRecordNotFound {
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"fusenapi/utils/encryption_decryption"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,19 +12,21 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfirmationLink[T any] struct {
|
type ConfirmationLink[T any] struct {
|
||||||
Secret []byte
|
// Secret []byte
|
||||||
|
SecretGCM *encryption_decryption.SecretGCM[T]
|
||||||
|
|
||||||
DefaultQueryKey string // 默认key 是 token
|
DefaultQueryKey string // 默认key 是 token
|
||||||
link *url.URL
|
link *url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfirmationLink[T any](key []byte, UrlStr string) *ConfirmationLink[T] {
|
func NewConfirmationLink[T any](key string, UrlStr string) *ConfirmationLink[T] {
|
||||||
u, err := url.Parse(UrlStr)
|
u, err := url.Parse(UrlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ConfirmationLink[T]{
|
return &ConfirmationLink[T]{
|
||||||
Secret: key,
|
SecretGCM: encryption_decryption.NewSecretGCM[T](key),
|
||||||
DefaultQueryKey: "token",
|
DefaultQueryKey: "token",
|
||||||
link: u,
|
link: u,
|
||||||
}
|
}
|
||||||
|
@ -62,91 +59,10 @@ func (cl *ConfirmationLink[T]) GenerateWithToken(token string) (string, error) {
|
||||||
return cl.link.String(), nil
|
return cl.link.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fusenMakeKey(keysting string) []byte {
|
|
||||||
|
|
||||||
key := []byte(keysting)
|
|
||||||
|
|
||||||
var result [32]byte
|
|
||||||
|
|
||||||
// If key length is more than 32, truncate it
|
|
||||||
if len(key) > 32 {
|
|
||||||
key = key[:32]
|
|
||||||
}
|
|
||||||
|
|
||||||
// If key length is less than 32, replicate it until it reaches 32
|
|
||||||
for len(key) < 32 {
|
|
||||||
key = append(key, key...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only take the first 32 bytes
|
|
||||||
key = key[:32]
|
|
||||||
|
|
||||||
// Swap the first 16 bytes with the last 16 bytes
|
|
||||||
copy(result[:], key[16:])
|
|
||||||
copy(result[16:], key[:16])
|
|
||||||
|
|
||||||
return result[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cl *ConfirmationLink[T]) Encrypt(obj *T) (string, error) {
|
func (cl *ConfirmationLink[T]) Encrypt(obj *T) (string, error) {
|
||||||
|
return cl.SecretGCM.Encrypt(obj)
|
||||||
var buf = bytes.NewBuffer(nil)
|
|
||||||
err := gob.NewEncoder(buf).Encode(obj)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
block, err := aes.NewCipher(cl.Secret)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
nonce := make([]byte, 12)
|
|
||||||
// if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
ciphertext := aesgcm.Seal(nonce, nonce, buf.Bytes(), nil)
|
|
||||||
|
|
||||||
return base64.URLEncoding.EncodeToString(ciphertext), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *ConfirmationLink[T]) Decrypt(ciphertext string) (*T, error) {
|
func (cl *ConfirmationLink[T]) Decrypt(ciphertext string) (*T, error) {
|
||||||
block, err := aes.NewCipher(cl.Secret)
|
return cl.SecretGCM.Decrypt(ciphertext)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ct, err := base64.URLEncoding.DecodeString(ciphertext)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ct) < 12 {
|
|
||||||
return nil, fmt.Errorf("ciphertext too short")
|
|
||||||
}
|
|
||||||
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
plaintext, err := aesgcm.Open(nil, ct[:12], ct[12:], nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解出golang的结构体
|
|
||||||
var protected T
|
|
||||||
var buf = bytes.NewBuffer(plaintext)
|
|
||||||
err = gob.NewDecoder(buf).Decode(&protected)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &protected, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"encoding/hex"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -19,7 +22,7 @@ func BenchmarkConfirmationLink(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
key := "21321321"
|
key := "21321321"
|
||||||
cl := NewConfirmationLink[Register](fusenMakeKey(key), "http://localhost:9900/api/auth/oauth2/register")
|
cl := NewConfirmationLink[Register](key, "http://localhost:9900/api/auth/oauth2/register")
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
|
||||||
uri, _ := cl.Generate(&Register{Id: 39, Password: "21dsadsad", platform: "google", Expired: time.Now()})
|
uri, _ := cl.Generate(&Register{Id: 39, Password: "21dsadsad", platform: "google", Expired: time.Now()})
|
||||||
|
@ -29,6 +32,87 @@ func BenchmarkConfirmationLink(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkAesXor(b *testing.B) {
|
||||||
|
// 生成一个256位的密钥
|
||||||
|
key := []byte("abcdefghijklmnopqrstuvwxyz123456")
|
||||||
|
|
||||||
|
// // 初始向量IV必须是唯一的,但不需要保密
|
||||||
|
iv := []byte("1234567890123456")
|
||||||
|
|
||||||
|
// // 要加密的明文
|
||||||
|
plaintext := []byte("hello world sadsadsadssadadsada ")
|
||||||
|
|
||||||
|
// // 使用AES加密,返回一个Block接口
|
||||||
|
// block, err := aes.NewCipher(key)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 使用CTR模式
|
||||||
|
// stream := cipher.NewCTR(block, iv)
|
||||||
|
|
||||||
|
// // 加密明文
|
||||||
|
// ciphertext := make([]byte, len(plaintext))
|
||||||
|
// stream.XORKeyStream(ciphertext, plaintext)
|
||||||
|
|
||||||
|
// // 转为hex编码打印出来
|
||||||
|
// // fmt.Println(hex.EncodeToString(ciphertext))
|
||||||
|
// ciphertextHex := hex.EncodeToString(ciphertext)
|
||||||
|
// // 将hex解码成[]byte
|
||||||
|
// ciphertext, _ = hex.DecodeString(ciphertextHex)
|
||||||
|
|
||||||
|
// // 生成Block接口
|
||||||
|
// block, err = aes.NewCipher(key)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 生成CTR模式
|
||||||
|
// stream = cipher.NewCTR(block, iv)
|
||||||
|
|
||||||
|
// // 解密密文
|
||||||
|
// plaintext = make([]byte, len(ciphertext))
|
||||||
|
// stream.XORKeyStream(plaintext, ciphertext)
|
||||||
|
|
||||||
|
// // 打印明文
|
||||||
|
// fmt.Println(string(plaintext))
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
// 使用AES加密,返回一个Block接口
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用CTR模式
|
||||||
|
stream := cipher.NewCTR(block, iv)
|
||||||
|
|
||||||
|
// 加密明文
|
||||||
|
ciphertext := make([]byte, len(plaintext))
|
||||||
|
stream.XORKeyStream(ciphertext, plaintext)
|
||||||
|
|
||||||
|
// 转为hex编码打印出来
|
||||||
|
// fmt.Println(hex.EncodeToString(ciphertext))
|
||||||
|
ciphertextHex := hex.EncodeToString(ciphertext)
|
||||||
|
// 将hex解码成[]byte
|
||||||
|
ciphertext, _ = hex.DecodeString(ciphertextHex)
|
||||||
|
|
||||||
|
// 生成Block接口
|
||||||
|
block, err = aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成CTR模式
|
||||||
|
stream = cipher.NewCTR(block, iv)
|
||||||
|
|
||||||
|
// 解密密文
|
||||||
|
plaintext = make([]byte, len(ciphertext))
|
||||||
|
stream.XORKeyStream(plaintext, ciphertext)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfirmationLink(t *testing.T) {
|
func TestConfirmationLink(t *testing.T) {
|
||||||
|
|
||||||
type Register struct {
|
type Register struct {
|
||||||
|
@ -40,7 +124,7 @@ func TestConfirmationLink(t *testing.T) {
|
||||||
|
|
||||||
key := "21321321"
|
key := "21321321"
|
||||||
|
|
||||||
cl := NewConfirmationLink[Register](fusenMakeKey(key), "http://localhost:9900/api/auth/oauth2/register")
|
cl := NewConfirmationLink[Register](key, "http://localhost:9900/api/auth/oauth2/register")
|
||||||
uri, _ := cl.Generate(&Register{Id: 39, Password: "21dsadsad", platform: "google", Expired: time.Now()})
|
uri, _ := cl.Generate(&Register{Id: 39, Password: "21dsadsad", platform: "google", Expired: time.Now()})
|
||||||
log.Println(uri)
|
log.Println(uri)
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 必须16字节
|
// 必须16字节
|
||||||
var key = "fusen20230405145"
|
var cbckey = "fusen20230405145"
|
||||||
|
|
||||||
// 加密(key必须16字节),前端加解密需要先把base64转字符串再取前16字节作为iv
|
// 加密(key必须16字节),前端加解密需要先把base64转字符串再取前16字节作为iv
|
||||||
func CBCEncrypt(data string) (string, error) {
|
func CBCEncrypt(data string) (string, error) {
|
||||||
|
@ -19,11 +19,11 @@ func CBCEncrypt(data string) (string, error) {
|
||||||
fmt.Println("cbc decrypt err:", err)
|
fmt.Println("cbc decrypt err:", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
block, err := aes.NewCipher([]byte(key))
|
block, err := aes.NewCipher([]byte(cbckey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
blockSize := len(key)
|
blockSize := len(cbckey)
|
||||||
padding := blockSize - len(data)%blockSize // 填充字节
|
padding := blockSize - len(data)%blockSize // 填充字节
|
||||||
if padding == 0 {
|
if padding == 0 {
|
||||||
padding = blockSize
|
padding = blockSize
|
||||||
|
@ -47,7 +47,7 @@ func CBCDecrypt(src string) (string, error) {
|
||||||
fmt.Println("cbc decrypt err:", err)
|
fmt.Println("cbc decrypt err:", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
block, err := aes.NewCipher([]byte(key))
|
block, err := aes.NewCipher([]byte(cbckey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
102
utils/encryption_decryption/aes_crt.go
Normal file
102
utils/encryption_decryption/aes_crt.go
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package encryption_decryption
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/gob"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ISecretEncDec interface {
|
||||||
|
EncodeToString([]byte) string
|
||||||
|
DecodeString(string) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecretCRT[T any] struct {
|
||||||
|
srcKey string
|
||||||
|
secretKey []byte
|
||||||
|
iv []byte
|
||||||
|
derivationKey func(keysting string) []byte
|
||||||
|
mu sync.Mutex
|
||||||
|
EncDec ISecretEncDec
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSecretCRT[T any](key string, iv string) *SecretCRT[T] {
|
||||||
|
s := &SecretCRT[T]{
|
||||||
|
derivationKey: DerivationKeyV1,
|
||||||
|
iv: []byte(iv),
|
||||||
|
EncDec: base64.URLEncoding,
|
||||||
|
}
|
||||||
|
s.secretKey = s.derivationKey(key)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretCRT[T]) UpdateDerivationKeyFunc(kfunc func(keysting string) []byte) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
s.derivationKey = kfunc
|
||||||
|
s.secretKey = s.derivationKey(s.srcKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretCRT[T]) Encrypt(gobj *T) (string, error) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
var buf = bytes.NewBuffer(nil)
|
||||||
|
err := gob.NewEncoder(buf).Encode(gobj)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用AES加密,返回一个Block接口
|
||||||
|
block, err := aes.NewCipher(s.secretKey)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用CTR模式
|
||||||
|
stream := cipher.NewCTR(block, s.iv)
|
||||||
|
|
||||||
|
// 加密明文
|
||||||
|
plaintext := buf.Bytes()
|
||||||
|
ciphertext := make([]byte, len(plaintext))
|
||||||
|
stream.XORKeyStream(ciphertext, plaintext)
|
||||||
|
|
||||||
|
// 转为hex编码打印出来
|
||||||
|
|
||||||
|
return s.EncDec.EncodeToString(ciphertext), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretCRT[T]) Decrypt(ciphertext string) (*T, error) {
|
||||||
|
// 将hex解码成[]byte
|
||||||
|
|
||||||
|
ciphertextbytes, err := s.EncDec.DecodeString(ciphertext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成Block接口
|
||||||
|
block, err := aes.NewCipher(s.secretKey)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成CTR模式
|
||||||
|
stream := cipher.NewCTR(block, s.iv)
|
||||||
|
|
||||||
|
// 解密密文
|
||||||
|
plaintext := make([]byte, len(ciphertextbytes))
|
||||||
|
stream.XORKeyStream(plaintext, ciphertextbytes)
|
||||||
|
|
||||||
|
// 解出golang的结构体
|
||||||
|
var protected T
|
||||||
|
var buf = bytes.NewBuffer(plaintext)
|
||||||
|
err = gob.NewDecoder(buf).Decode(&protected)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &protected, nil
|
||||||
|
}
|
129
utils/encryption_decryption/aes_gcm.go
Normal file
129
utils/encryption_decryption/aes_gcm.go
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
package encryption_decryption
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DerivationKeyV1(keysting string) []byte {
|
||||||
|
key := []byte(keysting)
|
||||||
|
|
||||||
|
var result [16]byte
|
||||||
|
|
||||||
|
// If key length is more than 32, truncate it
|
||||||
|
if len(key) > 16 {
|
||||||
|
key = key[:16]
|
||||||
|
}
|
||||||
|
|
||||||
|
// If key length is less than 32, replicate it until it reaches 32
|
||||||
|
for len(key) < 16 {
|
||||||
|
key = append(key, key...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only take the first 32 bytes
|
||||||
|
key = key[:16]
|
||||||
|
|
||||||
|
// Swap the first 16 bytes with the last 16 bytes
|
||||||
|
copy(result[:], key[8:])
|
||||||
|
copy(result[8:], key[:8])
|
||||||
|
|
||||||
|
return result[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecretGCM[T any] struct {
|
||||||
|
srcKey string
|
||||||
|
secretKey []byte
|
||||||
|
derivationKey func(keysting string) []byte
|
||||||
|
mu sync.Mutex
|
||||||
|
EncDec ISecretEncDec
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSecretGCM[T any](key string) *SecretGCM[T] {
|
||||||
|
s := &SecretGCM[T]{
|
||||||
|
srcKey: key,
|
||||||
|
derivationKey: DerivationKeyV1,
|
||||||
|
EncDec: base64.URLEncoding,
|
||||||
|
}
|
||||||
|
s.secretKey = s.derivationKey(s.srcKey)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretGCM[T]) UpdateDerivationKeyFunc(kfunc func(keysting string) []byte) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
s.derivationKey = kfunc
|
||||||
|
s.secretKey = s.derivationKey(s.srcKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretGCM[T]) Encrypt(gobj *T) (string, error) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
var buf = bytes.NewBuffer(nil)
|
||||||
|
err := gob.NewEncoder(buf).Encode(gobj)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
block, err := aes.NewCipher(s.secretKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
nonce := make([]byte, 12)
|
||||||
|
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ciphertext := aesgcm.Seal(nonce, nonce, buf.Bytes(), nil)
|
||||||
|
|
||||||
|
return s.EncDec.EncodeToString(ciphertext), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretGCM[T]) Decrypt(ciphertext string) (*T, error) {
|
||||||
|
block, err := aes.NewCipher(s.secretKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ct, err := s.EncDec.DecodeString(ciphertext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ct) < 12 {
|
||||||
|
return nil, fmt.Errorf("ciphertext too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
plaintext, err := aesgcm.Open(nil, ct[:12], ct[12:], nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解出golang的结构体
|
||||||
|
var protected T
|
||||||
|
var buf = bytes.NewBuffer(plaintext)
|
||||||
|
err = gob.NewDecoder(buf).Decode(&protected)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &protected, nil
|
||||||
|
}
|
90
utils/encryption_decryption/aes_obj_test.go
Normal file
90
utils/encryption_decryption/aes_obj_test.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package encryption_decryption_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/encryption_decryption"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGCM(t *testing.T) {
|
||||||
|
token := &auth.RegisterToken{
|
||||||
|
OperateType: auth.OpTypeRegister,
|
||||||
|
Password: "fusen_password",
|
||||||
|
WCId: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
key := "fusen123321"
|
||||||
|
|
||||||
|
gcm := encryption_decryption.NewSecretGCM[auth.RegisterToken](key)
|
||||||
|
tstr, err := gcm.Encrypt(token)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(tstr)
|
||||||
|
log.Println(gcm.Decrypt(tstr))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCRT(b *testing.B) {
|
||||||
|
token := &auth.RegisterToken{
|
||||||
|
OperateType: auth.OpTypeRegister,
|
||||||
|
Password: "fusen_password",
|
||||||
|
WCId: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
key := "fusen123321"
|
||||||
|
iv := "1234567890123456"
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
crt := encryption_decryption.NewSecretCRT[auth.RegisterToken](key, iv)
|
||||||
|
tstr, err := crt.Encrypt(token)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
crt.Decrypt(tstr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGCM(b *testing.B) {
|
||||||
|
token := &auth.RegisterToken{
|
||||||
|
OperateType: auth.OpTypeRegister,
|
||||||
|
Password: "fusen_password",
|
||||||
|
WCId: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
key := "fusen123321"
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
crt := encryption_decryption.NewSecretGCM[auth.RegisterToken](key)
|
||||||
|
tstr, err := crt.Encrypt(token)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
crt.Decrypt(tstr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCRT(t *testing.T) {
|
||||||
|
token := &auth.RegisterToken{
|
||||||
|
OperateType: auth.OpTypeRegister,
|
||||||
|
Password: "fusen_password",
|
||||||
|
WCId: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
key := "fusen123321"
|
||||||
|
iv := "1234567890123456"
|
||||||
|
|
||||||
|
crt := encryption_decryption.NewSecretCRT[auth.RegisterToken](key, iv)
|
||||||
|
tstr, err := crt.Encrypt(token)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(tstr)
|
||||||
|
log.Println(crt.Decrypt(tstr))
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user