1 Star 0 Fork 0

chaoyuechen / jetlic

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
main.go 7.32 KB
一键复制 编辑 原始数据 按行查看 历史
chaoyuechen 提交于 2024-04-14 21:30 . init
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"math/big"
"net/http"
"os"
"github.com/gin-gonic/gin"
)
var privateKey *rsa.PrivateKey
var crt *x509.Certificate
var rootCertificate = "-----BEGIN CERTIFICATE-----\n" +
"MIIFOzCCAyOgAwIBAgIJANJssYOyg3nhMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV\n" +
"BAMMDUpldFByb2ZpbGUgQ0EwHhcNMTUxMDAyMTEwMDU2WhcNNDUxMDI0MTEwMDU2\n" +
"WjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMIICIjANBgkqhkiG9w0BAQEFAAOC\n" +
"Ag8AMIICCgKCAgEA0tQuEA8784NabB1+T2XBhpB+2P1qjewHiSajAV8dfIeWJOYG\n" +
"y+ShXiuedj8rL8VCdU+yH7Ux/6IvTcT3nwM/E/3rjJIgLnbZNerFm15Eez+XpWBl\n" +
"m5fDBJhEGhPc89Y31GpTzW0vCLmhJ44XwvYPntWxYISUrqeR3zoUQrCEp1C6mXNX\n" +
"EpqIGIVbJ6JVa/YI+pwbfuP51o0ZtF2rzvgfPzKtkpYQ7m7KgA8g8ktRXyNrz8bo\n" +
"iwg7RRPeqs4uL/RK8d2KLpgLqcAB9WDpcEQzPWegbDrFO1F3z4UVNH6hrMfOLGVA\n" +
"xoiQhNFhZj6RumBXlPS0rmCOCkUkWrDr3l6Z3spUVgoeea+QdX682j6t7JnakaOw\n" +
"jzwY777SrZoi9mFFpLVhfb4haq4IWyKSHR3/0BlWXgcgI6w6LXm+V+ZgLVDON52F\n" +
"LcxnfftaBJz2yclEwBohq38rYEpb+28+JBvHJYqcZRaldHYLjjmb8XXvf2MyFeXr\n" +
"SopYkdzCvzmiEJAewrEbPUaTllogUQmnv7Rv9sZ9jfdJ/cEn8e7GSGjHIbnjV2ZM\n" +
"Q9vTpWjvsT/cqatbxzdBo/iEg5i9yohOC9aBfpIHPXFw+fEj7VLvktxZY6qThYXR\n" +
"Rus1WErPgxDzVpNp+4gXovAYOxsZak5oTV74ynv1aQ93HSndGkKUE/qA/JECAwEA\n" +
"AaOBhzCBhDAdBgNVHQ4EFgQUo562SGdCEjZBvW3gubSgUouX8bMwSAYDVR0jBEEw\n" +
"P4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2Zp\n" +
"bGUgQ0GCCQDSbLGDsoN54TAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq\n" +
"hkiG9w0BAQsFAAOCAgEAjrPAZ4xC7sNiSSqh69s3KJD3Ti4etaxcrSnD7r9rJYpK\n" +
"BMviCKZRKFbLv+iaF5JK5QWuWdlgA37ol7mLeoF7aIA9b60Ag2OpgRICRG79QY7o\n" +
"uLviF/yRMqm6yno7NYkGLd61e5Huu+BfT459MWG9RVkG/DY0sGfkyTHJS5xrjBV6\n" +
"hjLG0lf3orwqOlqSNRmhvn9sMzwAP3ILLM5VJC5jNF1zAk0jrqKz64vuA8PLJZlL\n" +
"S9TZJIYwdesCGfnN2AETvzf3qxLcGTF038zKOHUMnjZuFW1ba/12fDK5GJ4i5y+n\n" +
"fDWVZVUDYOPUixEZ1cwzmf9Tx3hR8tRjMWQmHixcNC8XEkVfztID5XeHtDeQ+uPk\n" +
"X+jTDXbRb+77BP6n41briXhm57AwUI3TqqJFvoiFyx5JvVWG3ZqlVaeU/U9e0gxn\n" +
"8qyR+ZA3BGbtUSDDs8LDnE67URzK+L+q0F2BC758lSPNB2qsJeQ63bYyzf0du3wB\n" +
"/gb2+xJijAvscU3KgNpkxfGklvJD/oDUIqZQAnNcHe7QEf8iG2WqaMJIyXZlW3me\n" +
"0rn+cgvxHPt6N4EBh5GgNZR4l0eaFEV+fxVsydOQYo1RIyFMXtafFBqQl6DDxujl\n" +
"FeU3FZ+Bcp12t7dlM4E0/sS1XdL47CfGVj4Bp+/VbF862HmkAbd7shs7sDQkHbU=\n" +
"-----END CERTIFICATE-----\n"
type License struct {
LicenseID string `json:"licenseId"`
LicenseeName string `json:"licenseeName"`
AssigneeName string `json:"assigneeName"`
AssigneeEmail string `json:"assigneeEmail"`
LicenseRestriction string `json:"licenseRestriction"`
CheckConcurrentUse bool `json:"checkConcurrentUse"`
Products []Product `json:"products"`
Metadata string `json:"metadata"`
Hash string `json:"hash"`
GracePeriodDays int `json:"gracePeriodDays"`
AutoProlongated bool `json:"autoProlongated"`
IsAutoProlongated bool `json:"isAutoProlongated"`
}
type Product struct {
Code string `json:"code"`
FallbackDate string `json:"fallbackDate"`
PaidUpTo string `json:"paidUpTo"`
Extended bool `json:"extended"`
}
func generateLicenseID() string {
const allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const licenseLength = 10
b := make([]byte, licenseLength)
for i := range b {
index, _ := rand.Int(rand.Reader, big.NewInt(int64(len(allowedCharacters))))
b[i] = allowedCharacters[index.Int64()]
}
return string(b)
}
func generateLicense(c *gin.Context) {
var license License
if err := c.ShouldBindJSON(&license); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
license.LicenseID = generateLicenseID()
licenseStr, _ := json.Marshal(license)
fmt.Printf("licenseStr:%s\n", licenseStr)
// Sign the license using SHA1withRSA
hashed := sha1.Sum(licenseStr)
signature, _ := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, hashed[:])
licensePartBase64 := base64.StdEncoding.EncodeToString(licenseStr)
signatureBase64 := base64.StdEncoding.EncodeToString(signature)
crtBase64 := base64.StdEncoding.EncodeToString(crt.Raw)
licenseResult := fmt.Sprintf("%s-%s-%s-%s", license.LicenseID, licensePartBase64, signatureBase64, crtBase64)
fmt.Printf("licenseResult:%s\n", licenseResult)
c.JSON(http.StatusOK, gin.H{"license": licenseResult})
}
func index(c *gin.Context) {
c.HTML(http.StatusOK, "/index.html", gin.H{
"title": "请选择",
"licenseeName": "Evaluator",
"assigneeName": "Evaluator",
"expiryDate": "2099-12-31",
})
}
// 生成power.conf配置
func generateEqualResult() {
// fmt.Println("x:证书的签名密文")
x := new(big.Int).SetBytes(crt.Signature)
// fmt.Println(x)
// fmt.Println("y:证书指数 固定65537")
y := 65537
// fmt.Println(y)
block, _ := pem.Decode([]byte(rootCertificate))
rootCertificate, err := x509.ParseCertificate(block.Bytes)
if err != nil {
panic("解析 rootCertificate 报错, 原因: " + err.Error())
}
// 其实是个固定的值,这里计算出来也行 jetbra-Z.txt里面
// fmt.Println("z:jetbra的内置根证书的公钥")
p, _ := rootCertificate.PublicKey.(*rsa.PublicKey)
z := p.N
// fmt.Println(z)
zp, _ := crt.PublicKey.(*rsa.PublicKey)
r := new(big.Int)
// 对证书验证其实就是验证证书中携带的签名是否和jetbains计算的签名是否一致,jetbrains会使用其内置根证书z尝试对签名解密,
// 即计算:x.modpow(y,z)(https://www.xuzhengtong.com/2022/07/25/secure/RSA/),但是这里的证书不是由jetbrains签发,所以要替换计算的结果为fakeResult,EQUAL,x,y,z->fakeResult中
r.Exp(x, big.NewInt(int64(y)), zp.N)
// fmt.Printf("r:modpow计算得到\n")
// fmt.Println(r)
fmt.Printf("EQUAL,%d,%d,%d->%d", x, y, z, r)
}
func cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
if origin != "" {
c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
}
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
c.Next()
}
}
func init() {
// Load private key and certificate
privateKeyPEM, err := os.ReadFile("./jetbra.key")
if err != nil {
panic("读取 jetbra.key 报错, 原因: " + err.Error())
}
block, _ := pem.Decode(privateKeyPEM)
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
panic("解析 jetbra.key 报错, 原因: " + err.Error())
}
crtPEM, err := os.ReadFile("./jetbra.pem")
if err != nil {
panic("读取 jetbra.pem 报错, 原因: " + err.Error())
}
block, _ = pem.Decode(crtPEM)
crt, err = x509.ParseCertificate(block.Bytes)
if err != nil {
panic("解析 jetbra.pem 报错, 原因: " + err.Error())
}
}
func main() {
//初始化路由
r := gin.Default()
r.Use(cors())
r.Static("static", "static")
//加载模板
r.LoadHTMLGlob("templates/*")
r.GET("/", index)
r.POST("/generateLicense", generateLicense)
r.Run("0.0.0.0:8080")
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/chaoyuechen/jetlic.git
git@gitee.com:chaoyuechen/jetlic.git
chaoyuechen
jetlic
jetlic
master

搜索帮助