package main import ( "flag" "fmt" "os" "strings" "github.com/gotunnel/plugins/tools/signtool/sign" ) func main() { if len(os.Args) < 2 { printUsage() os.Exit(1) } switch os.Args[1] { case "keygen": cmdKeygen() case "sign": cmdSign(os.Args[2:]) default: printUsage() os.Exit(1) } } func printUsage() { fmt.Println("GoTunnel Plugin Sign Tool") fmt.Println() fmt.Println("Usage:") fmt.Println(" signtool keygen") fmt.Println(" signtool sign -key KEY -name NAME -version VER FILE") } func cmdKeygen() { kp, err := sign.GenerateKeyPair() if err != nil { fmt.Fprintf(os.Stderr, "生成密钥失败: %v\n", err) os.Exit(1) } fmt.Println("=== 密钥对已生成 ===") fmt.Println() fmt.Println("私钥 (请妥善保管):") fmt.Println(sign.EncodePrivateKey(kp.PrivateKey)) fmt.Println() fmt.Println("公钥 (内置到客户端):") fmt.Println(sign.EncodePublicKey(kp.PublicKey)) } func cmdSign(args []string) { fs := flag.NewFlagSet("sign", flag.ExitOnError) keyFile := fs.String("key", "", "私钥文件路径") name := fs.String("name", "", "插件名称") version := fs.String("version", "", "插件版本") keyID := fs.String("keyid", "official-v1", "密钥 ID") fs.Parse(args) if *keyFile == "" || *name == "" || *version == "" || fs.NArg() < 1 { fmt.Println("用法: signtool sign -key KEY -name NAME -version VER FILE") os.Exit(1) } // 读取私钥 keyData, err := os.ReadFile(*keyFile) if err != nil { fmt.Fprintf(os.Stderr, "读取私钥失败: %v\n", err) os.Exit(1) } privKey, err := sign.DecodePrivateKey(strings.TrimSpace(string(keyData))) if err != nil { fmt.Fprintf(os.Stderr, "解析私钥失败: %v\n", err) os.Exit(1) } // 读取插件文件 pluginFile := fs.Arg(0) source, err := os.ReadFile(pluginFile) if err != nil { fmt.Fprintf(os.Stderr, "读取文件失败: %v\n", err) os.Exit(1) } // 创建载荷并签名 payload := sign.CreatePayload(*name, *version, string(source), *keyID) signed, err := sign.SignPlugin(privKey, payload) if err != nil { fmt.Fprintf(os.Stderr, "签名失败: %v\n", err) os.Exit(1) } // 写入签名文件 sigData, _ := sign.EncodeSignedPlugin(signed) sigFile := pluginFile + ".sig" if err := os.WriteFile(sigFile, []byte(sigData), 0644); err != nil { fmt.Fprintf(os.Stderr, "写入签名失败: %v\n", err) os.Exit(1) } fmt.Printf("签名成功: %s\n", sigFile) fmt.Printf(" 插件: %s v%s\n", *name, *version) fmt.Printf(" 哈希: %s\n", payload.SourceHash) }