聊天签名

This commit is contained in:
xmdhs 2023-09-12 00:09:30 +08:00
parent 4c87a43089
commit f9bba48f52
No known key found for this signature in database
GPG Key ID: E809D6D43DEFCC95
3 changed files with 81 additions and 1 deletions

View File

@ -69,7 +69,8 @@ func (y *Yggdrasil) YggdrasilRoot() httprouter.Handle {
Homepage: "", Homepage: "",
Register: "", Register: "",
}, },
ServerName: "test", ServerName: "test",
EnableProfileKey: true,
}, },
SignaturePublickey: string(y.pubkey), SignaturePublickey: string(y.pubkey),
SkinDomains: []string{host}, SkinDomains: []string{host},

View File

@ -75,9 +75,23 @@ type YggdrasilMeta struct {
ImplementationVersion string `json:"implementationVersion"` ImplementationVersion string `json:"implementationVersion"`
Links YggdrasilMetaLinks `json:"links"` Links YggdrasilMetaLinks `json:"links"`
ServerName string `json:"serverName"` ServerName string `json:"serverName"`
EnableProfileKey bool `json:"feature.enable_profile_key"`
} }
type YggdrasilMetaLinks struct { type YggdrasilMetaLinks struct {
Homepage string `json:"homepage"` Homepage string `json:"homepage"`
Register string `json:"register"` Register string `json:"register"`
} }
type Certificates struct {
ExpiresAt string `json:"expiresAt"`
KeyPair CertificatesKeyPair `json:"keyPair"`
PublicKeySignature string `json:"publicKeySignature"`
PublicKeySignatureV2 string `json:"publicKeySignatureV2"`
RefreshedAfter string `json:"refreshedAfter"`
}
type CertificatesKeyPair struct {
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
}

View File

@ -1,9 +1,15 @@
package yggdrasil package yggdrasil
import ( import (
"bytes"
"context" "context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math/big"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
@ -249,3 +255,62 @@ func (y *Yggdrasil) BatchProfile(ctx context.Context, names []string) ([]yggdras
} }
}), nil }), nil
} }
func (y *Yggdrasil) PlayerCertificates(ctx context.Context, token string) (yggdrasil.Certificates, error) {
t, err := sutils.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, &y.prikey.PublicKey, false)
if err != nil {
return yggdrasil.Certificates{}, fmt.Errorf("PlayerCertificates: %w", err)
}
rsa2048, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return yggdrasil.Certificates{}, fmt.Errorf("PlayerCertificates: %w", err)
}
s := sign.NewAuthlibSignWithKey(rsa2048)
priKey := lo.Must(s.GetPriKey())
pubKey := lo.Must(s.GetPubKey())
expiresAt := time.Now().Add(24 * time.Hour)
expiresAtUnix := expiresAt.UnixMilli()
pubV2 := publicKeySignatureV2(&rsa2048.PublicKey, t.Subject, expiresAtUnix)
pub := publicKeySignature(pubKey, expiresAtUnix)
servicePri := sign.NewAuthlibSignWithKey(y.prikey)
pubV2Base64 := lo.Must(servicePri.Sign(pubV2))
pubBase64 := lo.Must(servicePri.Sign(pub))
return yggdrasil.Certificates{
ExpiresAt: expiresAt.Format(time.RFC3339Nano),
KeyPair: yggdrasil.CertificatesKeyPair{
PrivateKey: priKey,
PublicKey: pubKey,
},
PublicKeySignature: pubBase64,
PublicKeySignatureV2: pubV2Base64,
RefreshedAfter: time.Now().Format(time.RFC3339Nano),
}, nil
}
func publicKeySignatureV2(key *rsa.PublicKey, uuid string, expiresAt int64) []byte {
bf := &bytes.Buffer{}
u := big.Int{}
u.SetString(uuid, 16)
bf.Write(u.Bytes())
eb := make([]byte, 8)
binary.BigEndian.PutUint64(eb, uint64(expiresAt))
bf.Write(eb)
bf.Write(x509.MarshalPKCS1PublicKey(key))
return bf.Bytes()
}
func publicKeySignature(key string, expiresAt int64) []byte {
bf := &bytes.Buffer{}
bf.WriteString(strconv.FormatInt(expiresAt, 10))
bf.WriteString(key)
return bf.Bytes()
}