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.Encode(license); err != nil {
panic(err)
} fmt.Println("可证文件生成成功")
} func main() {
MakeLicense()
}

这里的license信息比较简单,只有用户名,用户密钥,有效时间以及license的签名,也可以自己更具业务需要添加其他信息

使用公钥校验license

package main

import (
"bytes"
"crypto"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/gob"
"encoding/pem"
"fmt"
"os"
"time"
) var (
Username = "admin"
Secret = "secret-key-123"
) // 验证许可证签名
func verifyLicense(license *License, publicKey *rsa.PublicKey) error {
licenseCopy := *license
licenseCopy.Signature = nil var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
err := encoder.Encode(licenseCopy)
if err != nil {
return err
}
licenseData := buffer.Bytes() hash := sha256.Sum256(licenseData)
return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], license.Signature)
} func CheckLicense() {
// 读取公钥
publicKeyData, err := os.ReadFile("public.pem")
if err != nil {
panic(err)
}
publicBlock, _ := pem.Decode(publicKeyData)
publicKey, err := x509.ParsePKIXPublicKey(publicBlock.Bytes)
if err != nil {
panic(err)
}
rsaPublicKey, ok := publicKey.(*rsa.PublicKey)
if !ok {
panic("不是 RSA 公钥")
} // 读取二进制许可证
licenseData, err := os.ReadFile("license.lic")
if err != nil {
fmt.Println("未找到许可证文件")
return
} var license License
buffer := bytes.NewBuffer(licenseData)
decoder := gob.NewDecoder(buffer)
err = decoder.Decode(&license)
if err != nil {
fmt.Println("解析许可证文件失败")
return
} // 验证签名
err = verifyLicense(&license, rsaPublicKey)
if err != nil {
fmt.Println("许可证验证失败:", err)
return
} // 检查过期时间 这里是使用本地时间校验的,也可以通过网络时间校验
if time.Now().After(license.Expiration) {
fmt.Println("许可证已过期")
return
} // 检查用户名
if !(license.Username == Username && license.Secret == Secret) {
fmt.Println("许可证无效")
return
} fmt.Printf("许可证有效,程序可以运行,有效期至%s\n", license.Expiration.Format("2006-01-02 15:04:05"))
// 你的应用程序逻辑在这里
} func main() {
CheckLicense()
}

这里是通过本地时间来校验的有效性

这样做是有风险的,因为只要修改本地时间,就可以永远保证程序的有效性,这就导致license失去了意义

所以,可以通过网络时间来校验

或者循环检查本地时间,如果发现与网络时间相差太大,就不再允许使用程序

还有这里的用户名和密钥,可以通过网络进行校验,可以保证对程序的严格控制

go语言签发和验证license的更多相关文章

  1. 在node中使用jwt签发与验证token

    1.什么是token token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识. token是在服务端产生的.如果前端使用用户名和密码向服务端发送请求认证,服务端认证成功,那 ...

  2. AutoIT:界面与自动化操作结合来简化日常劳动: .Net Reactor验证License,设置License,创建License,截图AutoIt自动化实现。(七)

    版本六中存在一个显著问题是: 当exe文件生存之后,运行的时候,通过consoleWrite函数打印出来的数据是无法展示出来的.这就存在一个问题:当运行失败的时候,我还是看不到任何log信息. 于是, ...

  3. 操作 AutoIT:界面与自动化操作结合来简化日常劳动: .Net Reactor验证License,设置License,创建License,截图AutoIt自动化实现。(六)

    自动化操作的稳定性,便利性虽然已经满足了要求,但是页面上呈现的按钮太多了,可以做的更加简单一些. 1. 简化页面的按钮,把5个按钮减少至3个,把Display HID按钮功能整合到create lic ...

  4. Spring Boot项目中使用 TrueLicense 生成和验证License(服务器许可)

    一 简介 License,即版权许可证,一般用于收费软件给付费用户提供的访问许可证明.根据应用部署位置的不同,一般可以分为以下两种情况讨论: 应用部署在开发者自己的云服务器上.这种情况下用户通过账号登 ...

  5. 基于TrueLicense实现产品License验证功能

    受朋友所托,需要给产品加上License验证功能,进行试用期授权,在试用期过后,产品不再可用. 通过研究调查,可以利用Truelicense开源框架实现,下面分享一下如何利用Truelicense实现 ...

  6. 使用truelicense实现用于JAVA工程license机制(包括license生成和验证)

    开发的软件产品在交付使用的时候,往往会授权一段时间的试用期,这个时候license就派上用场了.不同于在代码中直接加上时间约束,需要重新授权的时候使用license可以避免修改源码,改动部署,授权方直 ...

  7. 基于 Token 的身份验证:JSON Web Token(附:Node.js 项目)

    最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等,比起传统的身份验证方法,Token 扩展性更强, ...

  8. 基于token的身份验证JWT

    传统身份验证的方法 HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用.这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下 ...

  9. 软件License设计

    如何保护软件版权,最常用的办法就是设计一套license验证框架. 1.我们的常规需求如下: .可以限制软件只能在一台机器上使用: 目前很多软件都是一机一码的销售,软件换一台机器则不能使用,想要几台机 ...

  10. IC验证概念总结

    一份代码,在写完之后,一定要再经过一次或多次整理和打磨,才能算完成的:一份代码,一定要把其有效代码行,精简.锤炼到最少.最短.最有效,才能算完成的.   下面这些问题和回答是忘记是在哪里看到的了,参考 ...

随机推荐

  1. .NET 代码混淆工具-JIEJIE.NET

    前言 JIEJIE.NET是一款强大的开源.NET程序集混淆工具.它利用深度加密技术和多样化的混淆策略,有效地保护了.NET软件的版权和源代码安全,防止未经授权的访问和篡改. 项目介绍 JIEJIE. ...

  2. 封装setItem 和 getItem 本地存储

    store.js 文件 按需导出setItem 和 getItem 函数 :在utils文件里面 : export const setItem = (key, value) => { // 复杂 ...

  3. 3. 王道OS-操作系统的运行机制,中断和异常

    1. 高级语言- 编译 - 机器指令 (二进制) 2. 内核态和用户态 :刚开机的时候CPU是内核态,当用户启动某个程序的时候CPU是用户态,如果遇到危险,操作系统会夺回CPU的控制权成为内核态,当危 ...

  4. 77.const声明对象修改对象里面的值会触发报错吗

    不会,因为对象是复杂类型数据 :对象的地址保存在栈内存中,对象的数据保存在堆内存中 : 只要对象的地址不发生改变,无论堆内存的对象数据如何改变,对象的值就不会改变 :

  5. 内核级流量治理引擎Kmesh八大新特性解读

    本文分享自华为云社区<内核级流量治理引擎 Kmesh v0.5 发布!进击的Sidecarless服务网格>,作者:云容器大未来. 我们非常高兴地宣布 Kmesh v0.5.0 的发布.首 ...

  6. 游戏推荐业务中基于 sentinel 的动态限流实践

    作者:来自 vivo 互联网服务器团队- Gao Meng 本文介绍了一种基于 sentinel 进行二次开发的动态限流解决方案,包括什么是动态限流.为什么需要引入动态限流.以及动态限流的实现原理. ...

  7. T3 出行云原生容器化平台实践

    公司简介 T3 出行是南京领行科技股份有限公司打造的智慧出行生态平台,由中国第一汽车集团有限公司.东风汽车集团有限公司.重庆长安汽车股份有限公司发起,联合腾讯.阿里巴巴等互联网企业共同投资打造.公司以 ...

  8. 基于 JuiceFS 的 KubeSphere DevOps 项目数据迁移方案

    方案背景和目的 KubeSphere 自发布以来已有 2 年之久,从 2.1.0 版本至目前最新版本 3.3.开发人员的编译构建都基于环境平台的 DevOps 功能(底层是 jenkins)实现,如果 ...

  9. git安装使用及连接gitlab集成idea

    一.简介 Git是一个开源的分布式版本控制系统,通过git可以对项目进行代码托管,通常配合GitLub.Github使用: 想了解更多请进官网(官网下载较慢):https://www.git-scm. ...

  10. bresenham算法(贝汉明算法)