完成所有的加密和加密链接

This commit is contained in:
eson
2023-07-28 12:15:56 +08:00
parent 3be161a011
commit 66808fc735
8 changed files with 422 additions and 99 deletions

View File

@@ -1,12 +1,7 @@
package auth
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/gob"
"fmt"
"fusenapi/utils/encryption_decryption"
"net/url"
)
@@ -17,19 +12,21 @@ const (
)
type ConfirmationLink[T any] struct {
Secret []byte
// Secret []byte
SecretGCM *encryption_decryption.SecretGCM[T]
DefaultQueryKey string // 默认key 是 token
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)
if err != nil {
panic(err)
}
return &ConfirmationLink[T]{
Secret: key,
SecretGCM: encryption_decryption.NewSecretGCM[T](key),
DefaultQueryKey: "token",
link: u,
}
@@ -62,91 +59,10 @@ func (cl *ConfirmationLink[T]) GenerateWithToken(token string) (string, error) {
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) {
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
return cl.SecretGCM.Encrypt(obj)
}
func (cl *ConfirmationLink[T]) Decrypt(ciphertext string) (*T, error) {
block, err := aes.NewCipher(cl.Secret)
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
return cl.SecretGCM.Decrypt(ciphertext)
}

View File

@@ -1,6 +1,9 @@
package auth
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"log"
"net/url"
"testing"
@@ -19,7 +22,7 @@ func BenchmarkConfirmationLink(b *testing.B) {
}
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++ {
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) {
type Register struct {
@@ -40,7 +124,7 @@ func TestConfirmationLink(t *testing.T) {
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()})
log.Println(uri)