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

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                使用TrueLicense来保护我们的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 licen;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"; // PRODUCT_ID  /**   * The subject for the license manager and also the alias of the private   * key entry in the keystore.   */  public static final String SUBJECT = "privatekey"; // CUSTOMIZE  /** The resource name of your private keystore file. */  public static final String KEYSTORE_RESOURCE = "privateKeys.store"; // 私匙库文件名  /** The password for the keystore. */  public static final String KEYSTORE_STORE_PWD = "a8a8a8"; // 私匙库密码  /* The password for the private key entry in the keystore. */  public static final String KEYSTORE_KEY_PWD = "a8a8a8"; //私匙库主键密码  /** The password to encrypt the generated license key file. */  public static final String CIPHER_KEY_PWD = "a8a8a8"; // 即将生成的license密码  /**   * 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"; // license.lic  //  // 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(2011,10,10);    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();    }  }}


           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/hfrujhv/article/details/84095094