聊天签名
This commit is contained in:
parent
4c87a43089
commit
f9bba48f52
@ -70,6 +70,7 @@ func (y *Yggdrasil) YggdrasilRoot() httprouter.Handle {
|
||||
Register: "",
|
||||
},
|
||||
ServerName: "test",
|
||||
EnableProfileKey: true,
|
||||
},
|
||||
SignaturePublickey: string(y.pubkey),
|
||||
SkinDomains: []string{host},
|
||||
|
@ -75,9 +75,23 @@ type YggdrasilMeta struct {
|
||||
ImplementationVersion string `json:"implementationVersion"`
|
||||
Links YggdrasilMetaLinks `json:"links"`
|
||||
ServerName string `json:"serverName"`
|
||||
EnableProfileKey bool `json:"feature.enable_profile_key"`
|
||||
}
|
||||
|
||||
type YggdrasilMetaLinks struct {
|
||||
Homepage string `json:"homepage"`
|
||||
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"`
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -249,3 +255,62 @@ func (y *Yggdrasil) BatchProfile(ctx context.Context, names []string) ([]yggdras
|
||||
}
|
||||
}), 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()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user