Files
jiu/backend/cmd/genkey/main.go
T
wangjia 40a80467ce feat(backend): Ed25519 license signing utilities (21A)
- util/license_key.go: LicensePayload struct, GenerateEd25519KeyPair,
  IssueLicenseToken (sign), VerifyLicenseToken (verify offline)
- cmd/genkey: one-shot keypair generator with demo sign+verify
- config: add Ed25519PublicKey field (LICENSE_ED25519_PUBLIC_KEY env)

Token format: base64url(header).base64url(payload).base64url(ed25519-sig)
Private key stored in Bitwarden; public key embedded in config/client.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:28:55 +08:00

60 lines
1.5 KiB
Go

// genkey generates an Ed25519 keypair for license signing.
// Run once; store the private key in Bitwarden and set the public key in config.
//
// Usage: go run ./cmd/genkey
package main
import (
"encoding/json"
"fmt"
"os"
"time"
"github.com/wangjia/jiu/backend/internal/util"
)
func main() {
priv, pub, err := util.GenerateEd25519KeyPair()
if err != nil {
fmt.Fprintf(os.Stderr, "failed to generate keypair: %v\n", err)
os.Exit(1)
}
fmt.Println("=== Ed25519 License Keypair ===")
fmt.Println()
fmt.Println("[Bitwarden] Private key (keep secret, never commit):")
fmt.Println(priv)
fmt.Println()
fmt.Println("[Config / LICENSE_ED25519_PUBLIC_KEY] Public key:")
fmt.Println(pub)
fmt.Println()
// Demo: issue and verify a sample token to confirm the keypair works
now := time.Now()
exp := now.Add(30 * 24 * time.Hour).Unix()
sample := util.LicensePayload{
ShopID: 1,
LicenseID: 1,
Type: "trial",
IssuedAt: now.Unix(),
ExpiresAt: &exp,
MaxDevices: 3,
}
token, err := util.IssueLicenseToken(sample, priv)
if err != nil {
fmt.Fprintf(os.Stderr, "demo sign failed: %v\n", err)
os.Exit(1)
}
verified, err := util.VerifyLicenseToken(token, pub)
if err != nil {
fmt.Fprintf(os.Stderr, "demo verify failed: %v\n", err)
os.Exit(1)
}
out, _ := json.MarshalIndent(verified, "", " ")
fmt.Println("[Demo] Sample token (30-day trial, shop_id=1):")
fmt.Println(token)
fmt.Println()
fmt.Println("[Demo] Verified payload:")
fmt.Println(string(out))
}