在网络游戏中,涉及到数据交互,也就涉及到加解密。后台使用golang,暂还不知道GDScript的解密如何做。
package main
import (
"fmt"
"net"
"os"
"strings"
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"encoding/pem"
)
// 加密相关 -----------------------------------------------------------
// md5验证
func MD5Str(src string) string {
h := md5.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}
// hmacsha256验证
func HMAC_SHA256(src, key string) string {
m := hmac.New(sha256.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}
// hmacsha512验证
func HMAC_SHA512(src, key string) string {
m := hmac.New(sha512.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}
func HMAC_SHA1(src, key string) string {
m := hmac.New(sha1.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}
// sha256验证
func SHA256Str(src string) string {
h := sha256.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}
// sha512验证
func SHA512Str(src string) string {
h := sha512.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}
// base编码
func BASE64EncodeStr(src string) string {
return string(base64.StdEncoding.EncodeToString([]byte(src)))
}
// base解码
func BASE64DecodeStr(src string) string {
a, err := base64.StdEncoding.DecodeString(src)
if err != nil {
return ""
}
return string(a)
}
var ivspec = []byte("0000000000000000")
func AESEncodeStr(src, key string) string {
block, err := aes.NewCipher([]byte(key))
if err != nil {
fmt.Println("key error1", err)
}
if src == "" {
fmt.Println("plain content empty")
}
ecb := cipher.NewCBCEncrypter(block, ivspec)
content := []byte(src)
content = PKCS5Padding(content, block.BlockSize())
crypted := make([]byte, len(content))
ecb.CryptBlocks(crypted, content)
return hex.EncodeToString(crypted)
}
func AESDecodeStr(crypt, key string) string {
crypted, err := hex.DecodeString(strings.ToLower(crypt))
if err != nil || len(crypted) == 0 {
fmt.Println("plain content empty")
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
fmt.Println("key error1", err)
}
ecb := cipher.NewCBCDecrypter(block, ivspec)
decrypted := make([]byte, len(crypted))
ecb.CryptBlocks(decrypted, crypted)
return string(PKCS5Trimming(decrypted))
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5Trimming(encrypt []byte) []byte {
padding := encrypt[len(encrypt)-1]
return encrypt[:len(encrypt)-int(padding)]
}
func RsaEncrypt(src, key string) string {
block, _ := pem.Decode([]byte(key))
if block == nil {
fmt.Println("?")
return ""
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
fmt.Println(err.Error())
return ""
}
pub := pubInterface.(*rsa.PublicKey)
crypted, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(src))
if err != nil {
fmt.Println(err.Error())
return ""
}
return hex.EncodeToString(crypted)
}
//RSA加密
// plainText 要加密的数据
// path 公钥匙文件地址
func RSA_Encrypt(plainText []byte, path string) []byte {
//打开文件
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()
//读取文件的内容
info, _ := file.Stat()
buf := make([]byte, info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//x509解码
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
//类型断言
publicKey := publicKeyInterface.(*rsa.PublicKey)
//对明文进行加密
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
if err != nil {
panic(err)
}
//返回密文
return cipherText
}
//RSA解密
// cipherText 需要解密的byte数据
// path 私钥文件路径
func RSA_Decrypt(cipherText []byte,path string) []byte{
//打开文件
file,err:=os.Open(path)
if err!=nil{
panic(err)
}
defer file.Close()
//获取文件内容
info, _ := file.Stat()
buf:=make([]byte,info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//X509解码
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err!=nil{
panic(err)
}
//对密文进行解密
plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey,cipherText)
//返回明文
return plainText
}
//生成私钥文件和公钥文件
//手动生成私钥 openssl genrsa -out rsa_private_key.pem 1024
//手动生民公钥 openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
func GenerateRSAKey(bits int) {
//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
//Reader是一个全局、共享的密码用强随机数生成器
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
panic(err)
}
//保存私钥
//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
//使用pem格式对x509输出的内容进行编码
//创建文件保存私钥
privateFile, err := os.Create("private.pem")
if err != nil {
panic(err)
}
defer privateFile.Close()
//构建一个pem.Block结构体对象
privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
//将数据保存到文件
pem.Encode(privateFile, &privateBlock)
//保存公钥
//获取公钥的数据
publicKey := privateKey.PublicKey
//X509对公钥编码
X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
panic(err)
}
//pem格式编码
//创建用于保存公钥的文件
publicFile, err := os.Create("public.pem")
if err != nil {
panic(err)
}
defer publicFile.Close()
//创建一个pem.Block结构体对象
publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
//保存到文件
pem.Encode(publicFile, &publicBlock)
}
func FileExist(path string) bool {
_, err := os.Lstat(path)
return !os.IsNotExist(err)
}
//----------------------------------------------------------------
func main() {
//AES加解密
key := "abcqlwekrjqwerjqwabcqlwekrjqwer1" //要求32位
say := "ok"
str := AESEncodeStr(say,key)
echo := AESDecodeStr(str,key)
fmt.Println("加密:",say," 加密后:",str, " 解密后:",echo)
//RSA加解密
//生成密钥对,保存到文件
if FileExist("public.pem")==false {
fmt.Println("生成密钥对,保存到文件")
GenerateRSAKey(2048)
}
//加密
data := []byte("hello world 中国")
encrypt := RSA_Encrypt(data, "public.pem")
//fmt.Println(string(encrypt))
// 解密
decrypt := RSA_Decrypt(encrypt, "private.pem")
fmt.Println("加密:",string(data)," 解密后:",string(decrypt))
return
//---------------------------------------------
address := "127.0.0.1:4242"
addr, err := net.ResolveUDPAddr("udp", address)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer conn.Close()
for {
// Here must use make and give the lenth of buffer
data := make([]byte, 300)
_, rAddr, err := conn.ReadFromUDP(data)
if err != nil {
fmt.Println(err)
continue
}
strData := string(data)
fmt.Println("Received:", strData)
upper := strings.ToUpper(strData)
_, err = conn.WriteToUDP([]byte(upper), rAddr)
if err != nil {
fmt.Println(err)
continue
}
fmt.Println("Send:", upper)
}
}
代码主要是演示用,核心也主要这样。