go语言签发和验证license
https://www.cnblogs.com/guangdelw/p/18328342
生成非对称密钥
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"os"
)
// MakePem 生成 PEM 文件
func MakePem() {
// 生成 RSA 密钥对
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
// 将私钥写入文件
privateFile, err := os.Create("private.pem")
if err != nil {
panic(err)
}
defer privateFile.Close()
privateBytes := x509.MarshalPKCS1PrivateKey(privateKey)
privateBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateBytes,
}
if err := pem.Encode(privateFile, privateBlock); err != nil {
panic(err)
}
// 提取公钥并写入文件
publicKey := &privateKey.PublicKey
publicBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
panic(err)
}
publicBlock := &pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: publicBytes,
}
publicFile, err := os.Create("public.pem")
if err != nil {
panic(err)
}
defer publicFile.Close()
if err := pem.Encode(publicFile, publicBlock); err != nil {
panic(err)
}
println("密钥生成成功")
}
func main() {
MakePem()
}
使用私钥来加密license
这里与其他非对称加密还不同,其他地方基本都是公钥加密,然后私钥解密
但是这里是私钥加密,然后公钥解密
这主要是为了保证license无法被篡改,而被解密倒相对次要一点
package main
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/gob"
"encoding/pem"
"fmt"
"os"
"time"
)
var (
Username = "admin"
Secret = "secret-key-123"
)
type License struct {
Username string `json:"username"` // 用户名
Secret string `json:"secret"` // 密钥
Expiration time.Time `json:"expiration"` // 到期时间
Signature []byte `json:"signature,omitempty"` // 签名
}
// 签名许可证
func signLicense(license *License, privateKey *rsa.PrivateKey) ([]byte, error) {
licenseCopy := *license
licenseCopy.Signature = nil // 签名前移除签名字段
// 使用gob编码
var licenseData []byte
buffer := new(bytes.Buffer)
encoder := gob.NewEncoder(buffer)
if err := encoder.Encode(licenseCopy); err != nil {
return nil, err
}
licenseData = buffer.Bytes()
hash := sha256.Sum256(licenseData)
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
if err != nil {
return nil, err
}
return signature, nil
}
var (
license = &License{
Username: Username,
Secret: Secret,
Expiration: time.Now().Add(30 * 24 * time.Hour), // 30 天后过期
}
)
func MakeLicense() {
// 读取私钥
privateKeyData, err := os.ReadFile("private.pem")
if err != nil {
panic(err)
}
privateBlock, _ := pem.Decode(privateKeyData)
privateKey, err := x509.ParsePKCS1PrivateKey(privateBlock.Bytes)
if err != nil {
panic(err)
}
// 签名许可证
signature, err := signLicense(license, privateKey)
if err != nil {
panic(err)
}
license.Signature = signature
// 将许可证编码为二进制格式
file, err := os.Create("license.lic")
if err != nil {
panic(err)
}
defer file.Close()
encoder := gob.NewEncoder(file)
if err := encoder.