在go语言中实现使用机器的唯一哈希值将可执行文件锁定在特定机器上示例
Go  /  管理员 发布于 1年前   279
我有个朋友正在寻找将 Golang 可执行文件锁定在客户办公室特定机器上的方法。
她的想法是不允许客户将可执行文件转移到另一台机器上,
也不允许潜在的竞争对手复制她的可执行文件回到自己的办公室进行学习。
她的公司采用的商业模式是按客户购买的软件许可证数量收费。-这是旧时代的产物。)
她计划用文件而不是加密狗来实现这种锁定机制。如何实现?
解决方案:
她可以创建一个单独的程序来生成一个文件,该文件只包含本机特有的哈希值,
如果将可执行文件转移到其他机器上,可执行文件将无法运行。
这将提示对方联系她寻求支持,并可能销售额外的新许可证。
示例代码:
generatelicense.go- 该文件不应与客户端共享!
package main
import (
"bufio"
"crypto/md5"
"fmt"
"github.com/shirou/gopsutil/host"
"io"
"os"
"os/exec"
"runtime"
"strings"
)
func dealwithErr(err error) {
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
func main() {
runtimeOS := runtime.GOOS
// 主机或机器内核、正常运行时间、平台信息
hostStat, err := host.Info()
dealwithErr(err)
fmt.Println("OS : ", runtimeOS)
fmt.Println("Host ID(uuid) : ", hostStat.HostID)
cmd := exec.Command("cat", "/proc/cpuinfo")
stdout, err := cmd.StdoutPipe()
dealwithErr(err)
err = cmd.Start()
dealwithErr(err)
defer cmd.Wait()
buff := bufio.NewScanner(stdout)
var result []string
for buff.Scan() {
result = append(result, buff.Text()+"\n")
}
//fmt.Println("cat /proc/cpuinfo : ")
//fmt.Println(result)
// 为这台机器生成唯一的哈希值
// 基于 /proc/cpuinfo 数据、操作系统名称和 UUID 的组合
hash := md5.New()
// 将切片转回字符串
resultString := strings.Join(result, "\n")
io.WriteString(hash, resultString+runtimeOS+hostStat.HostID)
fmt.Printf("该机器的唯一哈希值 : %x\n", hash.Sum(nil))
// 创建许可证文件
licenseFile, err := os.Create("./license.txt")
dealwithErr(err)
data := fmt.Sprintf("%x", hash.Sum(nil))
_, err = io.WriteString(licenseFile, data)
dealwithErr(err)
licenseFile.Close()
fmt.Println("Saved to license.txt")
}
并在安装过程中为客户端生成许可证文件。
生成许可证文件后,请安全擦除生成器程序。只需保留许可证文件,供可执行文件加载和检查。
mainexecutable.go
package main
import (
"bufio"
"crypto/md5"
"fmt"
"github.com/shirou/gopsutil/host"
"io"
"io/ioutil"
"os"
"os/exec"
"runtime"
"strings"
)
func dealwithErr(err error) {
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
func main() {
runtimeOS := runtime.GOOS
// 主机或机器内核、正常运行时间、平台信息
hostStat, err := host.Info()
dealwithErr(err)
cmd := exec.Command("cat", "/proc/cpuinfo")
stdout, err := cmd.StdoutPipe()
dealwithErr(err)
err = cmd.Start()
dealwithErr(err)
defer cmd.Wait()
buff := bufio.NewScanner(stdout)
var result []string
for buff.Scan() {
result = append(result, buff.Text()+"\n")
}
// 为这台机器生成唯一的哈希值
// 基于 /proc/cpuinfo 数据、操作系统名称和 UUID 的组合
hash := md5.New()
// 将切片转回字符串
resultString := strings.Join(result, "\n")
io.WriteString(hash, resultString+runtimeOS+hostStat.HostID)
thisMachineData := fmt.Sprintf("%x", hash.Sum(nil))
// 从 license.gob 文件读取并获得批准的哈希值
// 如果许可证文件中的哈希值与我们在此计算的哈希值不匹配
// 提示用户联系销售人员获取新许可证。
//打开许可证文件
licenseFile, err := ioutil.ReadFile("./license.txt")
dealwithErr(err)
licenseData := string(licenseFile)
if licenseData != thisMachineData {
fmt.Println("此可执行文件无法在本机上运行,请致电 11223344 或发送电子邮件至 [email protected] 购买新许可证")
os.Exit(0)
}
// 好的,文件中的许可证与这台机器的哈希值一致,因此继续
fmt.Println("License file is valid. Proceesing ..... ")
}
每次执行主可执行程序时,它都会根据提供的参数
(操作系统名称、CPU 信息和 UUID)生成一个 md5 哈希值。
如果生成的哈希值与许可证文件中的哈希值相同,则继续执行。
注意:
本实现过程保持简单,你可以根据自己的需要进一步改进。
例如,为软件许可协议添加到期日期或限制每个会话的用户数量等。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号