一篇文章通透理解序列号实现原理

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 序列号一般会和产品的名称(具体到硬件产品的型号、软件产品的版本号)、产品的使用期限(具体到截止日期)一起发布。

1.序列号的本质

序列号等价于注册码,是软件发行商的一种维权手段,也就是正版软件的一个身份证。本质:防止盗版、按功能收费等。
目前,商用软件和共享软件绝大部份都是采用注册码授权的方式来保证软件本身不被盗用,以保证自身的利益。尽管很多常用的许多软件系统的某些版本已经被别人破解,但对于软件特殊行业而言,注册码授权的方式还是一种保护软件系统本身的一种有效的手段。
序列号一般会和产品的名称(具体到硬件产品的型号、软件产品的版本号)、产品的使用期限(具体到截止日期)一起发布。
以下是一款我曾经试用过的美国软件产品Silver-peak注册码/序列号申请回复邮件的全文:

Hello,
The license key for your Silver Peak trial is ready to be installed.  This is one of two mails you will receive with unique license keys.  Deploy the Silver Peak Virtual Appliance you downloaded at each end of the WAN link you plan to optimize.  Once deployed, install the unique license key below on one appliance and the unique license key from the second email on the other appliance to enable optimization. 
Product: VX-2000
License Key:
P6F0-lBmL-34Pm-IZ3m-3MGL-s2ND-eLKC-+3pe-HROq-VMGQ-spH/-kOBb-LJOV-QC3p-nPw1-OJGy-KUem-egFc-sXWB-uDwm-goPa-gw==
Your license will expire on: Mon Jan 19 2015
Before you start your trial, we recommend you visit the Silver Peak Marketplace website and read the ‘Getting Started’ page: 
http://marketplace.silver-peak.com/products/vx-virtual-software/vx-2000.html 
If you have any questions about installing and configuring your virtual appliance, you can contact the Silver Peak support team directly.  The support team can be reached in one of three ways:
Via the support center at http://www.silverpeaksystems.com/support/portal_login.asp (you should have received an email with instructions on how to enable your account)
By phone at 877-210-7325 / 408-935-1850
By email at support@silver-peak.com

2.序列号/注册码的原理

一般是以计算机硬件(如主板,网卡,硬盘)的唯一序列号作为注册源,通过一定的算法(即注册机)形成所谓的注册码。一般的程序通过在程序中设置一个全局变量来进行注册码的记录。
Windows下次数可以在注册表里设置一个键值来判断,若有此键,则说明已经到期。(网上说法,个人感觉不可靠,因为注册表也可以修改。)
一般情况下软件的注册是通过比较来实现的,也就是说软件本身就是注册机,因为他本身就有个真正的注册码,用他来和你所输入的注册码做比较。不过有的是明码比较有的是加密比较,以明码比较来说:我们已经知道了软件自己可能会产生注册码的有的在内存中有的在软件中有的在注册表中,更有甚者是有个通用的万能注册码。
输入注册码成功是因为软件中用了跳转,也就是说。当你输入的号码和真正的注册码比较完的时候有个跳转。
大部分注册算法的原理是:软件或者用户自己触发了软件的注册模块软件跳转到注册认证模块。弹出注册窗口用户输入注册名+注册码A,把它们存放在内存中。然后软件的注册码验证部分根据用户输入的注册名生成正确的注册码B并和用户输入的注册码A做对比。如果结果为相同则注册通过,并运行“注册成功”后面的程序分支,比如解除各种软件限制。如果不相同则提示“无效的注册码,请重新输入!”或者“Invalid key!”等等警告。如下图所示:

image.png

图 1 注册截图

3.注册码/序列号授权分类

通常而言,注册码授权方式有以下几种方式:

(1)安装序列号方式

这是最为常用的方式,Mircosoft提供的产品(例如:Windows系列产品、Office系列产品等等)都是采用这种方式。通过一种复杂的算法生成安装序列号,在安装过程中,安装程序对用户输入的安装序列号进行校验来验证该系统是否被合法,从而完成授权。

image.png

图 2 Windows安装序列号方式

(2)用户名+序列号方式

即软件系统的供应商给用户提供有效的用户名和序列号,用户在安装过程或启动过程中输入有效的用户名和序列号,系统通过算法校验通过后完成软件授权。

image.png

图 3 用户名+序列号方式

(3)在线注册方式

用户安装系统后,通过网络进行注册授权。软件系统的供应商事先已经登记了用户的信息,用户在线注册时,供应商的注册系统对用户的信息进行验证。用户身份有效时,注册系统生成一个凭证信息,软件系统根据凭证信息完成授权。

image.png

图 4 在线注册方式

(4)激活码方式

用户安装系统后,软件系统会根据用户机器的关键信息(例如:MAC地址、CPU序列号、硬盘序列号等等)生成一个注册凭证(也可称为注册码),用户将这个注册凭证发送给软件供应商,供应商通过注册凭证生成一个激活码。用户输入激活码,软件系统完成授权。

image.png

图 5 激活码方式

4.注册码/序列号组成

(1)产品版本:限定具体到哪个版本、同产品的其他版本不能用。
(2)到期时间:限定截止服务运行时间,到给定截止前一周会有界面提示和邮件提醒。
(3)唯一标识:限定一个软件产品和MAC地址或者磁盘UUID(linux系统)/GUID(Windows系统)绑定。
(4)预留字段:用于分模块限定核心功能、分模块收费等。
以下是Silver-peak产品序列号使用期限截止前一周前邮件提示全文:
Hello,
This is to notify you that the Proof of Concept currently in process at XXX@163.com will expire on Wed Jan 21 2015.
This affects the following appliances, shipped on Mon Dec 22 2014:
VX-2000, S/N 001BBC03A8E9
VX-2000, S/N 001BBC03A8EA
If you have questions, please contact your account executive (Tricia Png, tpng@silver-peak.com).
Thank you,
Silver Peak Systems

5.获取机器的唯一标识

上面的分析可知,我们的软件肯定要安装到硬件设备上,为了管控乱拷贝现象或盗版使用现象,必须获取硬件设备的唯一标识。通过该唯一标识生成注册码/序列号。
有了设备的唯一编号,我们就可以实现更好的软件的授权机制,还可以利用它来限制客户端软件访问后台服务的权限,从而提高系统的安全性。
通用唯一识别码(英语:Universally Unique Identifier,简称UUID)是一种软件建构的标准,亦为自由软件基金会组织在分散式计算环境领域的一部份。
UUID的目的,是让分散式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的UUID,是微软公司的全局唯一标识符(GUID),而其他重要的应用,则有Linux ext2/ext3文件系统、LUKS加密分区、GNOME、KDE、Mac OS X等等。另外我们也可以在e2fsprogs包中的UUID库找到实现。
UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了全局唯一的IEEE机器识别号、纳秒级时间、芯片ID码和许多可能的数字。
如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同(实际测试结果每次都不同)。即每次生成的UUID都是不同的。
UUID由以下几部分的组合:


  • 1 全局唯一的IEEE机器识别号。(如果有网卡,从网卡MAC地址获得;没有网卡,以其他方式获得)
  • 2 纳秒级时间
  • 3 芯片ID码
  • 4 许多可能的数字

UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单地生成UUID,其格式为:xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个x是0-9 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)

5.1不同操作系统设备的唯一标识

(1)Windows系统GUID

全局唯一标识符,简称GUID(发音为/ˈɡuːɪd/或/ˈɡwɪd/),是一种由算法生成的唯一标识,通常表示成32个16进制数字(0-9,A-F)组成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它实质上是一个128位长的二进制整数。GUID一词有时也专指微软对UUID标准的实现。
GUID的主要目的是产生完全唯一的数字。在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID。GUID的总数也足够大,达到了2128(3.4×1038)个,所以随机生成两个相同GUID的可能性是非常小的,但并不为0。所以,用于生成GUID的算法通常都加入了非随机的参数(如时间),以保证这种重复的情况不会发生。
[维基百科]

(2)Linux系统UUID

Linux UUID的作用及意义
原因1:它是真正的唯一标志符
UUID为系统中的存储设备提供唯一的标识字符串,不管这个设备是什么类型的。如果你在系统中添加了新的存储设备如硬盘,很可能会造成一些麻烦,比如说启动的时候因为找不到设备而失败,而使用UUID则不会有这样的问题。
原因2:设备名并非总是不变的
自动分配的设备名称并非总是一致的,它们依赖于启动时内核加载模块的顺序。如果你在插入了USB盘时启动了系统,而下次启动时又把它拔掉了,就有可能导致设备名分配不一致。
使用UUID对于挂载移动设备也非常有好处──例如我有一个24合一的读卡器,它支持各种各样的卡,而使用UUID总可以使同一块卡挂载在同一个地方。
原因3:ubuntu中的许多关键功能现在开始依赖于UUID。
【长度缩减可以Base64编码】

5.2获取唯一标识方法

(1)Windows系统机器或者Linux系统机器获取方法

image.png

图 6 Windows机器的Guid

image.png

图 7 Linux机器的uuid
Windows系统&Linux系统获取uuid统一通用代码(已经测试过,测试结果见上面截图):

#include <stdio.h>
#include <string>
#include <iostream>

#ifdef WIN32
#include <objbase.h>
#else
#include <uuid/uuid.h>
#endif

using namespace std;

#define MAX_LEN 128


/*
**@brief: get windows guid or linux uuid
**@return: string type windows guid or linux uuid
*/
string GetGuid()
{
    char szuuid[MAX_LEN] = {0};
#ifdef WIN32
    GUID guid;
    CoCreateGuid(&guid);
    _snprintf_s(
        szuuid,
        sizeof(szuuid),
        "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
        guid.Data1, guid.Data2, guid.Data3,
        guid.Data4[0], guid.Data4[1],
        guid.Data4[2], guid.Data4[3],
        guid.Data4[4], guid.Data4[5],
        guid.Data4[6], guid.Data4[7]);
#else
    uuid_t uuid;
    uuid_generate(uuid);
    uuid_unparse(uuid, szuuid);
#endif

    return std::string(szuuid);
}

int main()
{
    string strGuid  = GetGuid();
    cout << strGuid.c_str() << endl;
    return 0;
}

(2)安卓手机设备(没有验证)

DEVICE_ID
这是Android系统为开发者提供的用于标识手机设备的串号,也是各种方法中普适性较高的,可以说几乎所有的设备都可以返回这个串号,并且唯一性良好。
这个DEVICE_ID可以同通过下面的方法获取:
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); String DEVICE_ID = tm.getDeviceId();
它会根据不同的手机设备返回IMEI,MEID或者ESN码,但在使用的过程中有以下问题:
非手机设备:最开始搭载Android系统都是手机设备,而现在也出现了非手机设备:如平板电脑、电子书、电视、音乐播放器等。这些设备没有通话的硬件功能,系统中也就没有TELEPHONY_SERVICE,自然也就无法通过上面的方法获得DEVICE_ID。
权限问题:获取DEVICE_ID需要READ_PHONE_STATE权限,如果只是为了获取DEVICE_ID而没有用到其他的通话功能,申请这个权限一来大才小用,二来部分用户会怀疑软件的安全性。
厂商定制系统中的Bug:少数手机设备上,由于该实现有漏洞,会返回垃圾,如:zeros或者asterisks
【参考】

5.3不使用MAC 地址作为唯一标识的原因

(1)有的Windows、Linux设备或者虚拟机可能没有网卡。

(2)对于安卓设备

可以使用手机Wifi或蓝牙的MAC地址作为设备标识,但是并不推荐这么做,原因有以下两点:
硬件限制:并不是所有的设备都有Wifi和蓝牙硬件,硬件不存在自然也就得不到这一信息。
获取的限制:如果Wifi没有打开过,是无法获取其Mac地址的;而蓝牙是只有在打开的时候才能获取到其Mac地址。

6.关于破解&安全性

不论是采用哪种方式来进行授权,理论上都是可以被破解的。只要破解者发现了软件授权机制和原理则任何保护机制都将化为乌有。因此,只能够通过选择复杂的算法和机制来增加破解者的破解难度,从而在在一定的时间内保证软件不被盗用。
RSA算法(非对称加密算法)是一个广泛用于加密和数字签名的算法,可以适用用户名+序列号、在线注册、激活码等软件保护方式。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA也是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
【参考RSA实现软件注册码原理】
设想的用户使用序列号的流程及可能存在的问题:

image.png

图 8 用户使用序列号流程

(1)联机验证是一种很好的防止破解的方法

优点:简单、高效、直观。
缺点:针对软件的使用客户情况不同,部分客户是内网机器,无法连接外网,也就无法联网验证。

(2)关于序列号拷贝问题

之前采用过一种方法,如果涉及两台设备(服务端、客户端)之间通信的,可以通过如下判定禁用复制序列号、修改Mac地址的情况。

image.png

图 9 通信的角度中断序列号复制问题

(3)UUID的弊端

如果将一台机器的UUID拷贝到另一台机器,就类似修改Mac地址的方法达到欺骗的目的。
由于目前没有找到通过UUID反推Mac地址的方法。设想的解密那里只能通过解密到UUID,不能继续解析到Mac地址或者磁盘UUID。
复杂一劳永逸的解决方案:UUID不通过系统生成,自己写算法生成。这样生成和解析都可控。
简单的解决方案:假定设备都装了网卡,通过实际网卡(非虚拟网卡)的Mac地址充当设备UUID。
安全性问题的以上3点需要花时间研究。

7.构想的序列号生成方案

下图是生成序列号与反查序列号界面截图(构想)。

image.png

图 10 序列号生成软件
下图是序列号生成流程图(构想)。
第一步:通过5.2(1)方法获取安装设备的UUID,如:
9d669361-7f8a-4f97-b08a-488e4a92ee52;该UUID应该存储在设备的软件安装路径一份,以备对比验证。
第二步:填写对应安装的软件版本号,如1.0.0.1;
第三步:填写使用或授权限定使用的期限,如3年。
第四步:点击生成序列号生成授权序列号(后台会调用RSA加密算法,对输入内容进行加密)。

image.png

图 11 序列号生成流程图
下图2是序列号验证逻辑流程图(构想)。
第一步:输入获取的序列号。
第二步:后台执行RSA解密序列号。
第三步:判定各个属性值和安装设备是否一致。
第四步:全部相同确定为有效序列号,可以放行软件功能权限。

image.png

图 12序列号验证逻辑流程图

8.参考

【1】UUID唯一资源命名空间的来龙去脉(RFC4122)
https://segmentfault.com/a/1190000000484508

【2】Linux磁盘分区UUID的获取及其UUID的作用
http://blog.chinaunix.net/uid-26517277-id-3240867.html

【3】Java平台生成GUID
http://www.cnblogs.com/jdonson/archive/2009/07/22/1528466.html

【4】各种OS生成UUID的方法
http://linfan.info/blog/2012/04/20/uuid/

【5】注册码的原理(可参考)
https://www.zhihu.com/question/20107987

【6】UUID的生成算法
http://blog.csdn.net/ubuntu64fan/article/details/1787891

【7】Windows修改Mac地址方法
http://jingyan.baidu.com/article/4b52d70266bde7fc5c774ba7.html


作者:铭毅天下
转载请标明出处,原文地址:http://blog.csdn.net/laoyang360/article/details/50966707
如果感觉本文对您有帮助,请点击‘顶’支持一下,您的支持是我坚持写作最大的动力,谢谢!

相关文章
|
6月前
|
数据库 对象存储
状态机的原理简析及重要用途
状态机的原理简析及重要用途
77 1
|
算法 安全 Java
快速了解常用的消息摘要算法,再也不用担心面试官的刨根问底
加密算法通常被分为两种:对称加密和非对称加密。其中,对称加密算法在加密和解密时使用的密钥相同;非对称加密算法在加密和解密时使用的密钥不同,分为公钥和私钥。此外,还有一类叫做消息摘要算法,是对数据进行摘要并且不可逆的算法。 这次我们了解一下消息摘要算法。
627 0
快速了解常用的消息摘要算法,再也不用担心面试官的刨根问底
|
缓存 算法 NoSQL
短链是什么原理?怎么实现呢?
内容营销中给用户推送营销消息最常见的方式就是发短信,比如三大运营商移动、联通、电信平时会发送一些诸如套餐办理、消费查询、话费充值这些短信,还有像银行、云服务厂商等等推送的各种包含查询服务的短信等等。
短链是什么原理?怎么实现呢?
|
小程序 Java 机器人
使用Java实现发送微信消息(附源码)_此程序在手再也不怕对象跟你闹了
此程序在手再也不怕女朋友跟你闹了!!!!自从有了女朋友比如:早安、晚安之类的问候语可不能断,但是也难免有时候会忘记那么该咋么办呢?很简单写一个程序么,近日闲来无趣想着用Java写一个自动发送微信的小程序,实现定时给指定的好友发送指定的消息,这不就很Nice了?本文主要包括实现的思路、代码的实现、打包为jar快捷方式!
150 0
|
Java 编译器
七千字带你了解封装等机制下
七千字带你了解封装等机制下
92 0
七千字带你了解封装等机制下
|
存储 SQL 安全
七千字带你了解封装等机制上
七千字带你了解封装等机制上
111 0
七千字带你了解封装等机制上
|
消息中间件 SQL 安全
25 张图,1.4 w字!彻底搞懂分布式事务原理(三)
本文提纲如下: 0. 前言 1. 单数据源事务 & 多数据源事务 2. 常见分布式事务解决方案 2.1. 分布式事务模型 2.2. 二将军问题和幂等性 2.3. 两阶段提交(2PC) & 三阶段提交(3PC)方案 2.4. TCC 方案 2.5. 事务状态表方案 2.6. 基于消息中间件的最终一致性事务方案 3. Seata in AT mode 的实现 3.1. Seata in AT mode 工作流程概述 3.2. Seata in AT mode 工作流程详述 4. 结束语
284 0
25 张图,1.4 w字!彻底搞懂分布式事务原理(三)
|
网络协议 安全 网络安全
我画了 42 张图就是为了让你搞懂计算机网络层(四)
前面我们学习了运输层如何为客户端和服务器输送数据的,提供进程端到端的通信。那么下面我们将学习网络层实际上是怎样实现主机到主机的通信服务的。几乎每个端系统都有网络层这一部分。所以,网络层必然是很复杂的。下面我将花费大量篇幅来介绍一下计算机网络层的知识。
我画了 42 张图就是为了让你搞懂计算机网络层(四)
|
算法 数据处理 调度
我画了 40 张图就是为了让你搞懂计算机网络层(一)
前面我们学习了运输层如何为客户端和服务器输送数据的,提供进程端到端的通信。那么下面我们将学习网络层实际上是怎样实现主机到主机的通信服务的。几乎每个端系统都有网络层这一部分。所以,网络层必然是很复杂的。下面我将花费大量篇幅来介绍一下计算机网络层的知识。
我画了 40 张图就是为了让你搞懂计算机网络层(一)
|
存储 缓存 网络协议
我画了 41 张图就是为了让你搞懂计算机网络层(二)
前面我们学习了运输层如何为客户端和服务器输送数据的,提供进程端到端的通信。那么下面我们将学习网络层实际上是怎样实现主机到主机的通信服务的。几乎每个端系统都有网络层这一部分。所以,网络层必然是很复杂的。下面我将花费大量篇幅来介绍一下计算机网络层的知识。
我画了 41 张图就是为了让你搞懂计算机网络层(二)