License管理流程和页面设计说明.docx
《License管理流程和页面设计说明.docx》由会员分享,可在线阅读,更多相关《License管理流程和页面设计说明.docx(26页珍藏版)》请在冰豆网上搜索。
License管理流程和页面设计说明
License(产品许可文件)
程序逻辑图
License发行时填的信息
客户的国家地区,所在的行业
客户联系人,客户电话,服务代表联系人,服务代表电话;
然后重新注册的理由可以通过下拉框进行选择,如果您重新注册的理由不属于列出项,可以在备注中进行补充,最后输入产品序列号、CDKEY、验证码,点击“提交”。
见红色标记。
●License管理
首先我们需要确立我们实现的管理目标
1、license资源使用的统计、管理和分析
2、CAD应用软件使用的统计和分析
3、用户使用情况的统计与分析
分配license给用户
对用户进行分组控制
将使用软件的所有用户分成若干组,对应于实际工作中的各个工作/项目组,每组具有不同的优先级。
每一组拥有的license种类、数量、运行时间窗口都可以由LSF来定义和管理。
根据用户优先级优化软件license的使用
用软件的不同用户/项目组具有不同的优先级。
当软件的license数量足够多时,用户都可以正常使用。
当软件license不足时,高优先级的用户作业将强行抢占低优先级的作业,保证紧要作业的及时完成。
License到期监控及预警
许可证到期预警信息窗口能够非常直观的显示各个功能模块的到期预警,以便用户续买License而不妨碍正常工作需求。
此窗口显示信息包括:
功能模块的到期时间、功能模块的供应商和软件所在的服务器信息。
许可证服务器预警界面默认显示到当前为止1个月内将到期的所有功能模块内容,每天晚上系统自动的将快到期的功能模块打包作为附件发送到指定的用户邮箱。
同时,用户可以自定义到期时间进行查询更短或更长时间到期的功能模块信息,查询的结果支持导出到Excel和TXT文件中。
License对应实时用户信息
许可证管理监控系统(ReporterLicense的统计分析)
许可证管理监控系统(LicenseReporter简称Reporter)统计本地或者全局的许可证服务器(LicenseServer)详细和准确的使用信息,这些服务器可以分布于任意位置,不同的时区。
同时支持查询实时信息和历史信息,以及支持查询离线使用情况(如外借情况)。
不仅能反映单个用户的License使用情况,也可反映单个部门(项目组或者分公司)的使用率,甚至也可反映整个企业的软件许可证(License)资源使用率。
1、 对软件的功能模块的使用效率进行报告,量化的数据使企业可以合理安排预算;
2、 对同一用户同时占用多个相同的license进行提醒,IT管理者可以做出适当的处理措施
3、 监控licenseserver的运行状况,一旦档机,立即报警
4、 集中监控和报告各类软件license使用情况、峰值时间、license到期信息、甚至硬件资
增强功能包括:
1、 自动收回用户占着却长时间不用的license;
2、 License调度,IT管理者可以决定是手动还是自动释放优先级低的用户的license给优先级高的用。
这是一个很好的功能,可以很好地调配公司的资源。
类似于车位,如果A拥有这个车位,当A不在时,可以允许B使用,当A来到时,B必须立刻让出车位给A
、
季度报表
服务器统计
杜绝软件许可证(License)资源的浪费
据研究调查发现,软件许可证(License)资源的浪费现象十分严重。
常见的浪费有:
员工未关闭程序就离开办公室、员工因License紧张早上抢占License、企业因License暂时紧张而多购License、企业因规模的变化导致License采购过多。
通过reporter模块您可以追踪多种类型的License使用率,并以此制定来年的采购计划,节约成本最高可达30%。
详细的使用信息
License过期预警邮件提示
许可证服务器(LicenseServer)异常状态邮件提醒
员工超长使用时间(超过24小时)提醒
自定义的SQL数据库查询
License使用的峰值报告
项目组/部门/子公司,每天/每周/每月/每季度使用软件许可证(License)资源的累计时间
四、结论
工欲善其事,必先利其器。
License管理系统的使用。
对宝贵的软件license进行监控和管理,可实现自动调配license,使license发挥更大的作用。
License的生成和验证
用KeyTool实现的一个简易License生成与验证系统
1.背景
公钥密码概念是由WhitfieldDiffie和MartinHellman于1976年提出的,他是密码学历史的一个重大成就。
公钥密码与以前的密码方法都大相径庭:
一是以前的密码算法都基于代换与置换操作,而公钥密码使用数学函数进行变换;二是公钥密码体制使用非对称的方式,使用两个密钥(加密密钥和解密密钥),而传统的密码算法仅使用一个密钥。
公钥密码体制的提出首先是为了解决利用传统密码体制进行密码分发时遇到的问题,数字签名时期后期应用的一个重要领域。
统观公钥密码算法,它们的数学基础是比较狭窄的。
大多数公钥密码算法都是基于如下三种数学难题之一的:
背包问题,给定一个互不相同的数组成的结合,要找出一个子集,其和为N;离散对数问题,如果p是素数q和M是整数,找出x使得gx ≡M(modp),或者就是基于椭圆曲线上的离散对数问题;因子分解问题,设N两个素数的乘积,找出满足一定关系的分解因子。
KeyTool
利用J2SDK提供的密钥对生成工具KeyTool生成基于DSA算法的密码对,并保存为JKS(JavaKeySource)形式的外部密码仓库文件。
在使用KeyTool过程中需要提供一些参数来完成对于所生成密码的设定,其中包括:
alias:
标识密码对字符串,保证在密码仓库内的唯一性。
并将作为在日后访问密码仓库时所使用的入口地址。
keyalg:
生成密码对时所采用的算法,这里将使用DSA作为默认密码算法。
dname:
记录有关密钥发放机构的字符串。
其内容的规范化表示细节参见KeyTool的相关帮助和技术文档。
keypass:
为所生成密钥对提供的密码,用于限制对其中私钥信息的访问。
只有在正确的提供了密码后,才可以访问密码仓库中相应私钥信息。
storepass:
初始化密码仓库时的密码,默认为第一次生成过程中所提供的密码仓库秘密码。
通过使用Java2SDK提供的KeyStore数据结构可以完成对密码仓库中已经存储密钥的查询和管理工作。
在实现过程中通过提供KeyStorage外层包装操作对象,来提供更为完善的对外部密码仓库文件访问的支持,包括读入一个JSK格式的密码仓库文件、获得密码仓库中的所有密码对入口地址、获得一个密码对的X.509格式公钥信息、判断当前密码仓库中是否存在特定的公钥信息。
2.流程
2.1 License文件生成流程
实现批量生成License文件的功能,其流程如下:
STEP1:
生成密钥对
1a:
密钥仓库是否存在,如不存在则重新建立
1b:
获得当前时间的Long型表示,将其设置为密钥访问入口地址
SETP2:
导出公钥文件(用于发送给终端用户)
2a:
提取出当前密钥仓库中的所有密钥访问入口地址
2b:
更具每个公钥访问入口地址,提取出其所对应的公钥信息
2c:
将公钥信息转换为X.509公钥体系结构表示
2d:
将公钥信息保存到外部的公钥文件
STEP3:
生成license文件
3a:
更具密钥仓库中的所有入口地址得到其所对应的私钥信息
3b:
读取license.properties文件
3c:
验证license.properties文件中的功能块信息
3d:
验证并添加所生成License的其实与终止时间
3e:
生成License信息将其保存为license_*****.lic文件
2.2 License文件验证流程
要求输入用于访问License文件的密码,和用于提取进行验证的公钥信息的序列码(这里实现为一个Long形的时间变量)。
其主要流程如下:
STEP1:
读取License文件和提取解析公钥信息
1a:
根据License文件访问密码对待验证文件进行访问
1b:
从公钥仓库中提取公钥信息
SETP2:
将License文件中的密文信息解码为明文信息
2a:
提取PRODUCT_ID信息,计算出模块运算优先级别
2b:
提取出验证文件中的有效起止时间
3.License文件生成
3.1加密密钥对生成
在生成密钥对过程中将利用long型的时间量,作为对于每个存储与.jsk文件中密钥对进行提取的入口地址。
另外通过buildKeyPairByTime()方法,可以机你小女冠批量化的密钥对生成。
在实现过程中,考虑到实际生成过程中的IO和系统调用耗时。
将相邻的两次密钥对生成间隔设置为500ms,保证不会发生前后两次生成结果的冲突。
最终所生成的密钥对信息将保存在keystore.jks文件中,该文件会有一个访问口令。
默认为在第一次生成密钥对时所提供的访问口令。
3.2验证信息导出
验证信息的导出,完成将上一步生成的密钥对中的公钥信息进行提取。
最终生成的publicCerts.jks文件将作为在客户端进行License认证时,所采用的公钥密码的提取仓库。
只要在正确的提供访问密码和访问入口信息,才可以进行正确的信息提取。
3.3生成License时的配置信息
值得一提的是,可以通过配置license.properties文件来完成对于所生成License文件的配置。
如下是一个标准的生成配置文件的内容:
列表1:
license.properties文件配置信息
#AddthepermittedproductIDhereforpartialusagelimitation
[1]PRODUCT_ID=*****_1.0;*****_1.0;*****_1.0;*****_1.0
#Thebasiclicenseinfomation
FIRSTNAME=*****
LASTNAME=*****
COMPANY=*****
ZIP=*****
COUNTRY=CHINA
STATE=BEIJING
CITY=BEIJING
STREET=*****
EMAIL=ohmyvince@
PHONE=(010)5
FAX=(010)51532404
#Outputlicenseencodingformation
ENCODING=ISO-8859-1
#Thegeneralpurchaseidentityforfurthercheck
PURCHASE_ID=GPI2006-06-05.076
#Thegeneralrunningnumberforfurthercheck
RUNNING_NO=GRN1493453
#Thelanguageidentityfortheproduct
LANGUAGE_ID=CN-GB2312
QUANTITY=1
REG_NAME=vince
RESELLER=KEG
#Thestartandfinishdateforvalidtionperiodofthelicensefile
#Shouldwiththeformat:
[2]START_DATE=2006.5.5
[3]FINISH_DATE=2006.10.10
[4]PURCHASE_DATE=2006.06.05
#Additionallicenseinfomation
ADDITIONAL1=
ADDITIONAL2=
在上边的配置文件中存在如下一些重要的配置选项:
在标记为[1]行处,通过指定PRODUCT_ID元素的内容来达到为所生成的License添加功能模块支持的目的。
这里通过用“;”隔开的一个字符串序列来添加不同的功能模块。
在标记为[2]~[4]行处,通过指定三个时间信息。
分别是License有效开始日期START_DATE、License失效日期FINISH_DATE 和License发放日期PURCHASE_DAT,完成指定生成License文件过程中用到的相关时间信息。
其他的配置信息,包含该License文件的一些其他基本信息。
4.License文件验证
4.1验证公钥信息提取
只有提供正确的License文件访问密码,和用于访问公钥仓库的SerialNumber才可以进行对License文件的验证。
完成从随License文件一起分发的publicCerts.jks文件中提取出用于解析的公钥信息。
4.2有效性验证
在得到了用于解析当前License文件的公钥信息后,如果可以正确的提取出License文件中的PlainText信息。
就可以对其中的特定数据进行有效性验证。
有效性验证包含如下两个方面:
包括格式验证:
防止文件损坏或恶意篡改。
时间验证:
在特定的使用区间内方可生效。
4.3支持功能模块验证
功能模块化验证通过计算运行优先级来判定当前用户可以使用的软件功能。
利用二进制位向量来表示某个License对于特定软件功能的支持。
其中包括如下主要部分。
功能模块编码:
将所有的功能模块分散到不同的二进制位上。
并规定如果该位为1,则表示持有当前License文件的用户可以调用该软件功能。
如果为0,则表示不可以调用。
计算运行优先级:
完成将一个License文件所提供的功能模块支持信息,转换为一个二进制数字向量。
编制功能检查掩码:
需要为每个功能模块定义其功能检查掩码。
5.后继
在开源软件滚滚大潮中,加密软件与软件私有化已经显示的越来越落伍了。
这一点对于Java语言而言显示的格外明显。
不能否认上边给出的这种加密方法,只是在原理层面给出了一种可行的解决方案。
由于存在很多的安全漏洞,并不适与实际加密系统的使用。
但是无奈与可笑的是,对于各种商业软件,即使使用多么复杂的代码扰乱与加密技术的研究,最终来还不是会出现在盗版小贩手中?
......
java中使用公钥加密私钥解密原理实现license控制
现在很多J2EE应用都采用一个license文件来授权系统的使用,特别是在系统购买的早期,会提供有限制的license文件对系统进行限制,比如试用版有譬如IP、日期、最大用户数量的限制等。
而license控制的方法又有很多,目前比较流行,只要设计的好就很难破解的方法就是采用一对密匙(私匙加密公匙解密)来生成License文件中的Sinature签名内容,再通过Base64或Hex来进行编码。
比如原BEA公司现在是Oracle公司的WebLogic就采用的是这种方法来设置License文件。
这里只进行一个比较简单的实现:
一共三个类:
A.KeyGenerater类生成公钥私钥对
B.Signaturer类使用私钥进行签名
C.SignProvider类用公钥验证
公钥和私钥使用Base64加密Base64这个类很多地方都可以查到。
KeyGenerater类:
public class KeyGenerater {
private byte[] priKey;
private byte[] pubKey;
public void generater() {
try {
KeyPairGenerator keygen = KeyPairGenerator .getInstance("RSA");
SecureRandom secrand = new SecureRandom();
secrand.setSeed("www.川江号子.cn".getBytes()); // 初始化随机产生器
keygen.initialize(1024, secrand);
KeyPair keys = keygen.genKeyPair();
PublicKey pubkey = keys.getPublic();
PrivateKey prikey = keys.getPrivate()
pubKey = Base64.encodeToByte(pubkey.getEncoded());
priKey = Base64.encodeToByte(prikey.getEncoded());
System.out.println("pubKey = " + new String(pubKey));
System.out.println("priKey = " + new String(priKey));
} catch (java.lang.Exception e) {
System.out.println("生成密钥对失败");
e.printStackTrace();
}
}
public byte[] getPriKey() {
return priKey;
}
public byte[] getPubKey() {
return pubKey;
}
}
Signaturer 类:
public class Signaturer {
public static byte[] sign(byte[] priKeyText, String plainText) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(priKeyText));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey prikey = keyf.generatePrivate(priPKCS8);
// 用私钥对信息生成数字签名
Signature signet = java.security.Signature.getInstance("MD5withRSA");
signet.initSign(prikey);
signet.update(plainText.getBytes());
byte[] signed = Base64.encodeToByte(signet.sign());
return signed;
} catch (java.lang.Exception e) {
System.out.println("签名失败");
e.printStackTrace();
}
return null;
}
}
SignProvider 类:
public class SignProvider {
private SignProvider() {
}
public static boolean verify(byte[] pubKeyText, String plainText,
byte[] signText) {
try {
// 解密由base64编码的公钥,并构造X509EncodedKeySpec对象
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(Base64.decode(pubKeyText));
// RSA对称加密算法
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(bobPubKeySpec);
// 解密由base64编码的数字签名
byte[] signed = Base64.decode(signText);
Signature signatureChecker = Signature.getInstance("MD5withRSA");
signatureChecker.initVerify(pubKey);
signatureChecker.update(plainText.getBytes());
// 验证签名是否正常
if (signatureChecker.verify(signed))
return true;
else
return false;
} catch