`

使用TrueLicense来保护我们的JAVA软件产品

    博客分类:
  • Java
阅读更多

我们的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();
    }
  }

}

分享到:
评论

相关推荐

    使用 TrueLicense来保护我们的JAVA软件产品.doc

    TrueLicense 提供了一种灵活且安全的方法来管理 Java 软件产品的许可证,有助于保护开发者的知识产权,同时为合法用户提供便捷的授权体验。通过合理的配置和实施,TrueLicense 可以有效地防止软件盗版,增加收入,并...

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

    总的来说,TrueLicense为Java开发者提供了一套强大的许可证管理系统,通过它,你可以轻松地在你的项目中实现许可证的生成和验证,有效保护软件权益。结合提供的`LicenseCreate`和`LicenseVerify`示例代码,你可以...

    使用truelicense进行Java程序license控制 经过扩张可以验证license 开始结束日期,验证绑定给定mac地址

    总结来说,Truelicense是Java开发中用于软件许可管理的强大工具,它可以实现MAC地址绑定、有效期验证等功能,从而提升软件的安全性和合法性。通过提供的完整jar和测试代码,开发者能够更方便地学习和使用这个库,以...

    基于truelicense实现JAVA工程license机制(压缩包内有生成和验证)

    在Java开发中,为了保护软件不被非法使用,开发者通常会采用授权机制,即license机制。TrueLicense是一款强大的Java许可管理工具,它可以帮助开发者轻松地为自己的Java应用程序添加许可功能。本教程将深入探讨如何...

    truelicense实现用于JAVA工程license机制(添加mac验证)

    首先,`TrueLicense`的核心是通过生成加密的许可证文件(在本例中为"License"文件)来控制软件的使用权限。这些文件包含了特定的密钥和条件,例如有效期、功能限制等,只有当用户提供的许可证文件满足这些条件时,...

    TrueLicense证书生成工具

    TrueLicense是一款强大的软件许可管理系统,它为开发者提供了一种安全且灵活的方式来保护自己的软件产品,防止未经授权的使用。本文将详细介绍TrueLicense证书生成工具及其在Windows x64平台上的使用。 TrueLicense...

    到java.net下载truelicense

    TrueLicense是一个用于Java应用程序的许可管理系统,它可以帮助开发者保护他们的软件免受非法复制和使用。它允许软件供应商创建、管理和验证许可证密钥,从而控制软件的使用权限。 在描述中提到的“博文链接:...

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

    在Java开发中,为了保护软件知识产权,防止未经授权的使用,开发者常常需要引入许可证(License)机制。TrueLicense是一个强大的开源工具,专为Java应用程序提供许可证管理功能,它可以帮助开发者生成和验证许可证,...

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

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

    java truelicense-demo

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

    TrueLicense使用帮助中文版

    TrueLicense在设计时考虑到了安全性:您的知识产权通过对许可密钥进行数字签名和对字符串常量以及软件的字节码进行模糊处理得到保护。通过对许可密钥进行加密,可以保护客户的隐私。该API允许您配置由安装在JRE中的...

    SpringBoot 整合 TrueLicense 实现 License 的授权与服务器许可1

    在本文中,我们将探讨如何使用SpringBoot与TrueLicense框架进行整合,以便实现软件的授权和服务器许可管理。TrueLicense是一个强大的许可管理系统,可以帮助开发者保护他们的应用程序免受非法使用。 首先,我们需要...

    truelicense 添加mac验证

    在这个主题中,我们将深入探讨如何使用truelicense为软件添加MAC(Machine Authentication Code,机器认证码)验证,这是一种防止软件盗版和非法复制的有效方法。 MAC验证是一种特定类型的硬件绑定,它要求软件运行...

    Python-用于生成证书和TrueLicense许可证的Python库

    总结来说,Python库如`licepy`为开发者提供了一种方便的方式来管理和保护他们的软件许可证,确保软件的合法使用。结合其他安全相关的Python库,如`pyOpenSSL`和`cryptography.io`,可以构建出一套完整的安全机制,为...

    true-license源码+中文注释

    总结来说,`TrueLicense`是一个强大的工具,通过其源码和中文注释,开发者不仅可以了解软件授权的基本原理,还能深入学习Java加密技术和软件安全策略。无论是对于个人项目还是商业软件,集成`TrueLicense`都是保护...

    javaEE防盗版-License开发

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

    truelicense-core-1.32.jar

    truelicense-core-1.32.jar\\license授权机制的jar包,

    TrueLicense实现系统证书授权

    TrueLicense实现系统证书授权,详细描述见-&gt;https://blog.csdn.net/taotao_guiwang/article/details/127250547

    truelicense-by Kevin.zip

    truelicense

Global site tag (gtag.js) - Google Analytics