- 浏览: 102547 次
- 性别:
- 来自: 深圳
文章分类
最新评论
我们的JAVA软件产品有时需要限制非法用户,只有购买了LICENSE的用户才能使用,因此,我们可以通过TrueLicense来实现。 首先要用KeyTool工具来生成私匙库: 然后把私匙库内的公匙导出到一个文件当中: 然后再把这个证书文件导入到公匙库:keytool -genkey -alias privatekey -keystore privateKeys.store
keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store
keytool -import
-alias publiccert -file certfile.cer -keystore publicCerts.store
服务器端利用私匙库来创建license的代码例子:
package
com.sourceware.license;
import
de.schlichtherle.license.*;
import
java.io.*;
import
java.util.*;
import
javax.security.auth.x500.X500Principal;
import
java.util.prefs.Preferences;
/**
* <p>Title: CMVP通用媒体增值业务平台</p>
*
* <p>Description: CMVP通用媒体增值业务平台</p>
*
* <p>Copyright: Copyright (c) 2005</p>
*
* <p>Company: source-ware.com inc.</p>
*
* @author 黑山
* @version 2.0
*/
public
class SWLicenseManager {
public
SWLicenseManager() {
}
LicenseContent verifyLicenseKey(LicenseParam parameter) {
// Create a configured license manager.
LicenseManager manager = new
LicenseManager(parameter);
try
{
// Verify the previously installed current license certificate.
return
manager.verify();
}
catch
(Exception exc) {
System
.err.println("Could not verify license key"
);
exc.printStackTrace();
return
null
;
}
}
void installLicenseKey(LicenseParam parameter, File keyFile) {
// Create a configured license manager.
LicenseManager manager = new
LicenseManager(parameter);
try
{
// Load the license key, verify and install it as the current license key.
manager.install(keyFile);
}
catch
(Exception exc) {
System
.err.println("Could not install license certificate"
);
exc.printStackTrace();
}
}
void createLicenseKey(LicenseParam parameter, LicenseContent content) {
// Create a configured license manager.
LicenseManager manager = new
LicenseManager(parameter);
try
{
// Create the license key from the license content and save it to a file.
manager.store(content, new
File("license.lic"
));
}
catch
(Exception exc) {
System
.err.println("Could not save license key"
);
exc.printStackTrace();
}
}
//
// Customizable global properties.
//
/** The product id of your software */
public
static
final
String
PRODUCT_ID = "cmvp20"
; // CUSTOMIZE
/**
* The subject for
the license manager and also the alias of the private
* key entry in the keystore.
*/
public
static
final
String
SUBJECT = "别名"
; // CUSTOMIZE
/** The resource name of your private
keystore file. */
public
static
final
String
KEYSTORE_RESOURCE = "私匙库文件名"
; // CUSTOMIZE
/** The password for
the keystore. */
public
static
final
String
KEYSTORE_STORE_PWD = "私匙库密码"
; // CUSTOMIZE
/* The password for
the private
key entry in the keystore. */
public
static
final
String
KEYSTORE_KEY_PWD = "私匙库主键密码"
; // CUSTOMIZE
/** The password to encrypt the generated license key file. */
public
static
final
String
CIPHER_KEY_PWD = "即将生成的license密码"
; // CUSTOMIZE
/**
* The filename to be displayed for
the generated binary key file when
* delivered. Please note that this
is not used to write to a file of
* this
name.
*/
public
static
final
String
DISPLAY_FILENAME = "license.lic"
; // CUSTOMIZE
//
// The rest
of this
key generator does not need to get customized.
//
/** The MIME type of the generated binary key file. */
public
static
final
String
MIME_TYPE = "application/octet-stream"
;
//
// Possible key generator exit codes
//
/**
* Return <code>ERC_SUCCESS</code> on succesful creation of a textual key.
* Note that this
example creates a binary key and thus this
constant is not
* used here
*/
//public
static
final
int
ERC_SUCCESS = 00;
/**
* Return <code>ERC_SUCCESS_BIN</code> on succesful creation of a binary
* key. (Which could contain text as well, if
the content type is specified
* as <code>text/plain</code>)
*/
public
static
final
int
ERC_SUCCESS_BIN = 01;
/**
* Return <code>ERC_ERROR</code> for
general errors.
*/
public
static
final
int
ERC_ERROR = 10;
/**
* Return <code>ERC_MEMORY</code> if
memory allocation fails.
*/
public
static
final
int
ERC_MEMORY = 11;
/**
* Return <code>ERC_FILE_IO</code> on IOException
*/
public
static
final
int
ERC_FILE_IO = 12;
/**
* Return <code>ERC_BAD_ARGS</code> if
the command line parameters are
* bad.
*/
public
static
final
int
ERC_BAD_ARGS = 13;
/**
* Return <code>ERC_BAD_INPUT</code> if
a particular input value is
* missing or has a bad value. Don't forget to supply a meaningful error
* message naming the exact cause of the error.
*/
public
static
final
int
ERC_BAD_INPUT = 14;
/**
* Return <code>ERC_EXPIRED</code> if
this
generator is expired. This can
* be used to limit the lifetime of this
generator.
*/
//public
static
final
int
ERC_EXPIRED = 15;
/**
* Return <code>ERC_INTERNAL</code> if
an unhandled exception occurs.
*
* @see java.lang.Exception
*/
//public
static
final
int
ERC_INTERNAL = 16;
/** Encoding keys in properties. */
public
static
final
String
ENCODING_KEY = "ENCODING"
;
public
static
final
String
PRODUCT_ID_KEY = "PRODUCT_ID"
;
public
static
final
String
PURCHASE_ID_KEY = "PURCHASE_ID"
;
public
static
final
String
RUNNING_NO_KEY = "RUNNING_NO"
;
public
static
final
String
PURCHASE_DATE_KEY = "PURCHASE_DATE"
;
public
static
final
String
LANGUAGE_ID_KEY = "LANGUAGE_ID"
;
public
static
final
String
QUANTITY_KEY = "QUANTITY"
;
public
static
final
String
REG_NAME_KEY = "REG_NAME"
;
public
static
final
String
ADDITIONAL1_KEY = "ADDITIONAL1"
;
public
static
final
String
ADDITIONAL2_KEY = "ADDITIONAL2"
;
public
static
final
String
RESELLER_KEY = "RESELLER"
;
public
static
final
String
LASTNAME_KEY = "LASTNAME"
;
public
static
final
String
FIRSTNAME_KEY = "FIRSTNAME"
;
public
static
final
String
COMPANY_KEY = "COMPANY"
;
public
static
final
String
EMAIL_KEY = "EMAIL"
;
public
static
final
String
PHONE_KEY = "PHONE"
;
public
static
final
String
FAX_KEY = "FAX"
;
public
static
final
String
STREET_KEY = "STREET"
;
public
static
final
String
ZIP_KEY = "ZIP"
;
public
static
final
String
CITY_KEY = "CITY"
;
public
static
final
String
STATE_KEY = "STATE"
;
public
static
final
String
COUNTRY_KEY = "COUNTRY"
;
/** Default encoding for
properties. */
public
static
final
String
ENCODING_PROPERTIES = "ISO-8859-1"
;
/** Default share-it encoding if
key not present in properties. */
public
static
final
String
ENCODING_DEFAULT = ENCODING_PROPERTIES;
protected
static
final
LicenseManager manager = new
LicenseManager(
new
DefaultLicenseParam(
SUBJECT,
Preferences.userRoot(),
new
DefaultKeyStoreParam(
SWLicenseManager.class, // CUSTOMIZE
KEYSTORE_RESOURCE,
SUBJECT,
KEYSTORE_STORE_PWD,
KEYSTORE_KEY_PWD),
new
DefaultCipherParam(CIPHER_KEY_PWD)));
/**
* Validates the properties and generates a license certificate file.
*/
private
static
void generateLicense(Properties props, File certFile) throws
Exception {
// Check for
supported product id.
final
String
productId = props.getProperty(PRODUCT_ID_KEY);
if
(!PRODUCT_ID.equals(productId)) {
throw
new
BadInputException("Bad product ID: "
+ productId);
}
final
StringBuffer
dn = new
StringBuffer
();
addAttribute(dn, "CN"
, props.getProperty(FIRSTNAME_KEY)
+ ' ' + props.getProperty(LASTNAME_KEY));
if
(dn.length() == 0) {
addAttribute(dn, "CN"
, props, REG_NAME_KEY);
}
addAttribute(dn, "O"
, props, COMPANY_KEY);
addAttribute(dn, "STREET"
, props, STREET_KEY);
addAttribute(dn, "L"
, props.getProperty(ZIP_KEY)
+ ' ' + props.getProperty(CITY_KEY));
addAttribute(dn, "ST"
, props, STATE_KEY);
addAttribute(dn, "C"
, props, COUNTRY_KEY);
final
X500Principal holder = new
X500Principal(dn.toString());
final
X500Principal issuer = new
X500Principal(
"OU=share-it!,O=element 5 AG,STREET=Vogelsanger Strasse 78,L=50823 K\u00F6ln,ST=Nordrhein-Westfalen,C=DE"
);
final
LicenseContent content = new
LicenseContent();
content.setHolder(holder);
content.setIssuer(issuer);
content.setConsumerType("User"
);
content.setConsumerAmount(1);
content.setInfo(props.toString());
content.setSubject(SUBJECT);
java.util.Calendar cal =java.util.Calendar.getInstance();
cal.set(2006,1,1);
content.setNotAfter(cal.getTime());
manager.store(content, certFile);
}
private
static
final
void addAttribute(
final
StringBuffer
dn,
final
String
oid,
final
Properties props,
final
String
key) {
addAttribute(dn, oid, props.getProperty(key));
}
private
static
void addAttribute(
final
StringBuffer
dn,
final
String
oid,
String
value) {
if
(value == null
) {
return
;
}
final
String
trimmedValue = value.trim();
if
("".equals(trimmedValue)) {
return
;
}
// See http://www.ietf.org/rfc/rfc2253.txt
boolean
quote = false
;
if
(!value.equals(trimmedValue)) {
quote = true
;
}
else
if
(value.matches(".*[+,;<>\"
].*")) {
;
}
quote = true
;
if
(dn.length() != 0) {
dn.append(',');
}
dn.append(oid);
dn.append('=');
if
(quote) {
dn.append('"');
}
// Replace every single backslash with two backslashes
// whereas both parameters are expressed as regular expressions.
value = value.replaceAll("\\\\"
, "\\\\\\\\"
);
// Replace every single quote with an escaped quote
// whereas both parameters are expressed as regular expressions.
value = value.replaceAll("\"
", "
\\\\\"");
dn.append(value);
if
(quote) {
dn.append('"');
}
}
private
static
Properties readInput(String
pathname) throws
IOException {
Properties props = new
EncodedProperties();
InputStream in = new
FileInputStream(pathname);
try
{
props.load(in);
}
catch
(IllegalArgumentException iae) {
throw
new
BadInputException(iae);
}
finally
{
in.close();
}
return
props;
}
/**
* This is the main entry point for
JAVA key generators. It processes the
* command line arguments, loads and parses the input file, calls the key
* generator and writes output files.
*
* JAVA Exceptions are handled and transformed into key generator error
* codes. Exception messages will be written to <code>args[1]</code> and
* display on the error console.
*/
public
static
int
KeyMain(String
args[]) {
args = new
String
[3];
args[0] = "license.properties"
;
args[1] = "license.status"
;
args[2] = "license.lic"
;
if
(args.length != 3) {
System
.err.println("Usage: <input> <output1> <output2>"
);
return
ERC_BAD_ARGS;
}
int
errorCode = ERC_ERROR;
PrintWriter out = new
PrintWriter(System
.err);
try
{
try
{
// Read input and get encoding
final
Properties props = readInput(args[0]);
final
String
encoding
= props.getProperty(ENCODING_KEY, ENCODING_DEFAULT);
// Setup real output with encoding read from input file.
out = new
PrintWriter(
new
OutputStreamWriter(
new
FileOutputStream(args[1]),
encoding));
// Validate input and generate key file.
generateLicense(props, new
File(args[2]));
// Write status.
out.write(MIME_TYPE + ":"
+ DISPLAY_FILENAME);
}
catch
(BadInputException bie) {
errorCode = ERC_BAD_INPUT;
throw
bie;
}
catch
(IOException ioe) {
errorCode = ERC_FILE_IO;
throw
ioe;
}
catch
(OutOfMemoryError oome) {
errorCode = ERC_MEMORY;
throw
oome;
}
}
catch
(Throwable t) {
out.println("Error #"
+ errorCode);
t.printStackTrace(out);
return
errorCode;
}
finally
{
out.close();
}
return
ERC_SUCCESS_BIN;
}
/**
* NOTE: This main() method is never called by the actual key server. It is
* just useful for
debugging the key generator.
*/
public
static
final
void main(String
args[]) {
KeyMain(args);
/*try
{
manager.install(new
java.io.File("swutil.log"
));
System
.out.println("subject="
+ manager.verify().getSubject());
System
.exit(0);
}catch
(Exception ex){
ex.printStackTrace();
}*/
}
public
static
class EncodedProperties
extends
Properties {
public
EncodedProperties() {
this
(new
Properties());
}
/**
* @throws
NullPointerException if
<tt>defaults</tt> is <tt>null
</tt>.
*/
public
EncodedProperties(Properties defaults) {
super
(defaults);
// Make sure we have a proper default
for
the encoding.
defaults.setProperty(ENCODING_KEY, ENCODING_DEFAULT);
}
public
void load(InputStream inStream) throws
IOException {
super
.load(inStream);
String
encoding = super
.getProperty(ENCODING_KEY);
if
(ENCODING_PROPERTIES.equals(encoding)) {
return
;
}
// Convert properties
try
{
Map.Entry[] entries = new
Map.Entry[entrySet().size()];
entrySet().toArray(entries);
for
(int
i = entries.length; --i >= 0; ) {
Map.Entry entry = entries[i];
String
value = (String
) entry.getValue();
value = new
String
(value.getBytes(ENCODING_PROPERTIES),
encoding);
setProperty( (String
) entry.getKey(), value);
}
}
catch
(UnsupportedEncodingException ignored) {}
}
}
public
static
class BadInputException
extends
IOException {
public
BadInputException(String
message) {
super
(message);
}
public
BadInputException(Throwable cause) {
initCause(cause);
}
}
}
客户端程序安装license以及检验license合法性的代码:
安全警告
不要把私匙库拷贝到客户端,而只拷贝公匙库,要不然黑客就可以用你的私匙库来生成许许多多的license了package
com.sourceware.cmvp.license;
import
de.schlichtherle.license.*;
import
java.io.*;
import
java.util.*;
import
javax.security.auth.x500.X500Principal;
import
java.util.prefs.Preferences;
/**
* <p>Title: CMVP通用媒体增值业务平台</p>
*
* <p>Description: CMVP通用媒体增值业务平台</p>
*
* <p>Copyright: Copyright (c) 2005</p>
*
* <p>Company: source-ware.com inc.</p>
*
* @author 黑山
* @version 2.0
*/
public
class CMVPLicenseManager {
public
CMVPLicenseManager() {
}
/** The product id of your software */
public
static
final
String
PRODUCT_ID = "cmvp20"
; // CUSTOMIZE
/**
* The subject for
the license manager and also the alias of the private
* key entry in the keystore.
*/
public
static
final
String
SUBJECT = "别名"
; // CUSTOMIZE
/** The resource name of your private
keystore file. */
public
static
final
String
KEYSTORE_RESOURCE = "公匙库文件名"
; // CUSTOMIZE
/** The password for
the keystore. */
public
static
final
String
KEYSTORE_STORE_PWD = "公匙库密码"
; // CUSTOMIZE
/** The password to encrypt the generated license key file. */
public
static
final
String
CIPHER_KEY_PWD = "license文件密码"
; // CUSTOMIZE
protected
static
final
LicenseManager manager = new
LicenseManager(
new
DefaultLicenseParam(
SUBJECT,
Preferences.userNodeForPackage(CMVPLicenseManager.class),
new
DefaultKeyStoreParam(
CMVPLicenseManager.class, // CUSTOMIZE
KEYSTORE_RESOURCE,
SUBJECT,
KEYSTORE_STORE_PWD,
null
),//这里一定要是null
new
DefaultCipherParam(CIPHER_KEY_PWD)));
/**
* NOTE: This main() method is never called by the actual key server. It is
* just useful for
debugging the key generator.
*/
public
static
final
void main(String
args[]) {
try
{
manager.install(new
java.io.File("license.lic"
));
String
subject = manager.verify().getSubject();
System
.out.println("subject========"
+subject);
}
catch
(Exception ex) {
ex.printStackTrace();
}
}
}
发表评论
-
java 压缩API
2012-10-16 09:53 929从 Java 支持压缩/解压缩开始,无法缺省支持中文文件名。 ... -
字符编码
2012-09-19 22:53 10231、Java文件编译后形成cl ... -
SSL
2012-06-01 07:27 996JAVA 双向SSL,SOCKET客户端/服务端 [/size ... -
XML选择器
2012-03-30 13:24 589xpath路径表达式笔记 http://www.rua ... -
异常体系
2012-03-27 22:20 673http://hi.baidu.com/hivemind/bl ... -
JAXB
2012-03-30 13:24 1091HashMap support: http://www.ch ... -
OS-WS-ARCH
2012-04-01 09:48 1021参数名称 描述 o ... -
线程文摘
2012-04-01 09:48 726ThreadLocal http://blog.csdn.n ... -
Java regex
2011-10-16 09:15 935(a(b)*) 匹配规则见下文红色描述 (a( ... -
编码规范
2010-12-02 19:43 933一.为什么要有编码规 ... -
多线程-实战篇
2010-06-15 20:47 758在进入实战篇以前,我们简单说一下多线程编程的一般原则。 ... -
多线程-基础篇
2010-06-15 18:21 737写在前面 随着计 ...
相关推荐
TrueLicense 提供了一种灵活且安全的方法来管理 Java 软件产品的许可证,有助于保护开发者的知识产权,同时为合法用户提供便捷的授权体验。通过合理的配置和实施,TrueLicense 可以有效地防止软件盗版,增加收入,并...
总的来说,TrueLicense为Java开发者提供了一套强大的许可证管理系统,通过它,你可以轻松地在你的项目中实现许可证的生成和验证,有效保护软件权益。结合提供的`LicenseCreate`和`LicenseVerify`示例代码,你可以...
总结来说,Truelicense是Java开发中用于软件许可管理的强大工具,它可以实现MAC地址绑定、有效期验证等功能,从而提升软件的安全性和合法性。通过提供的完整jar和测试代码,开发者能够更方便地学习和使用这个库,以...
在Java开发中,为了保护软件不被非法使用,开发者通常会采用授权机制,即license机制。TrueLicense是一款强大的Java许可管理工具,它可以帮助开发者轻松地为自己的Java应用程序添加许可功能。本教程将深入探讨如何...
首先,`TrueLicense`的核心是通过生成加密的许可证文件(在本例中为"License"文件)来控制软件的使用权限。这些文件包含了特定的密钥和条件,例如有效期、功能限制等,只有当用户提供的许可证文件满足这些条件时,...
TrueLicense是一款强大的软件许可管理系统,它为开发者提供了一种安全且灵活的方式来保护自己的软件产品,防止未经授权的使用。本文将详细介绍TrueLicense证书生成工具及其在Windows x64平台上的使用。 TrueLicense...
TrueLicense是一个用于Java应用程序的许可管理系统,它可以帮助开发者保护他们的软件免受非法复制和使用。它允许软件供应商创建、管理和验证许可证密钥,从而控制软件的使用权限。 在描述中提到的“博文链接:...
在Java开发中,为了保护软件知识产权,防止未经授权的使用,开发者常常需要引入许可证(License)机制。TrueLicense是一个强大的开源工具,专为Java应用程序提供许可证管理功能,它可以帮助开发者生成和验证许可证,...
基于truelicense实现用于JAVA工程license机制(包括license生成和验证)
开发的软件产品在交付使用的时候,往往会授权一段时间的试用期,这个时候license就派上用场了。不同于在代码中直接加上时间约束,需要重新授权的时候使用license可以避免修改源码,改动部署,授权方直接生成一个新的...
TrueLicense在设计时考虑到了安全性:您的知识产权通过对许可密钥进行数字签名和对字符串常量以及软件的字节码进行模糊处理得到保护。通过对许可密钥进行加密,可以保护客户的隐私。该API允许您配置由安装在JRE中的...
在本文中,我们将探讨如何使用SpringBoot与TrueLicense框架进行整合,以便实现软件的授权和服务器许可管理。TrueLicense是一个强大的许可管理系统,可以帮助开发者保护他们的应用程序免受非法使用。 首先,我们需要...
在这个主题中,我们将深入探讨如何使用truelicense为软件添加MAC(Machine Authentication Code,机器认证码)验证,这是一种防止软件盗版和非法复制的有效方法。 MAC验证是一种特定类型的硬件绑定,它要求软件运行...
总结来说,Python库如`licepy`为开发者提供了一种方便的方式来管理和保护他们的软件许可证,确保软件的合法使用。结合其他安全相关的Python库,如`pyOpenSSL`和`cryptography.io`,可以构建出一套完整的安全机制,为...
总结来说,`TrueLicense`是一个强大的工具,通过其源码和中文注释,开发者不仅可以了解软件授权的基本原理,还能深入学习Java加密技术和软件安全策略。无论是对于个人项目还是商业软件,集成`TrueLicense`都是保护...
开发的软件产品在交付使用的时候,往往会授权一段时间的试用期,这个时候license就派上用场了。不同于在代码中直接加上时间约束,需要重新授权的时候使用license可以避免修改源码,改动部署,授权方直接生成一个新的...
truelicense-core-1.32.jar\\license授权机制的jar包,
TrueLicense实现系统证书授权,详细描述见->https://blog.csdn.net/taotao_guiwang/article/details/127250547
truelicense