美文网首页
1.使用license项目证书管理

1.使用license项目证书管理

作者: _少年不知愁 | 来源:发表于2022-07-28 16:33 被阅读0次

    1.license

    代码地址

    通过license控制项目证书验证
    
    我才用的TrueLicense实现lic
    
    首先介绍下 license 授权机制的原理:
        生成密钥对,包含私钥和公钥。
        授权者保留私钥,使用私钥对授权信息诸如使用截止日期,mac 地址等内容生成 license 签名证书。
        公钥给使用者,放在代码中使用,用于验证 license 签名证书是否符合使用条件
    

    2.生成公私钥

    1.生成私钥
    keytool -genkey -alias privatekey -keystore privateKeys.store -keysize 1024 -validity 3650
    //-validity 3650 表示有效期为10年
    // 我这边设值密码为123456a, 密令执行成功会产生文件privateKeys.store
    
    2.生成certfile.cer(证书)
    keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store
    
    3.生成 publicCerts.store
    keytool -import -alias publiccert -file certfile.cer -keystore publicCerts.store
    
    
    lic1.png

    3.生成licence.lic

    api "de.schlichtherle.truelicense:truelicense-core:1.33"
    

    licenseCreator

    /**
     * License生成类 -- 用于license生成
     */
    public class LicenseCreator {
    
        private final static X500Principal DEFAULT_HOLDER_AND_ISSUER = new X500Principal("CN=a, OU=a, O=a, L=a, ST=a, C=a");
    
        private static Logger logger = LogManager.getLogger(LicenseCreator.class);
    
        private License license;
    
        public LicenseCreator(License license) {
            this.license = license;
        }
    
        /**
         * 生成License证书
         */
        public boolean generateLicense() {
            try {
                LicenseManager licenseManager = new CustomLicenseManager(initLicenseParam());
                LicenseContent licenseContent = initLicenseContent();
                licenseManager.store(licenseContent, new File(license.getLicensePath()));
                return true;
            } catch (Exception e) {
                logger.error(MessageFormat.format("证书生成失败:{0}", license), e);
                return false;
            }
        }
    
        /**
         * 初始化证书生成参数
         */
        private LicenseParam initLicenseParam() {
            Preferences preferences = Preferences.userNodeForPackage(LicenseCreator.class);
    
            //设置对证书内容加密的秘钥
            CipherParam cipherParam = new DefaultCipherParam(license.getStorePass());
    
            KeyStoreParam privateStoreParam = new CustomKeyStoreParam(LicenseCreator.class
                    , license.getPrivateKeysStorePath()
                    , license.getPrivateAlias()
                    , license.getStorePass()
                    , license.getKeyPass());
    
            return new DefaultLicenseParam(license.getSubject()
                    , preferences
                    , privateStoreParam
                    , cipherParam);
        }
    
        /**
         * 设置证书生成正文信息
         */
        private LicenseContent initLicenseContent() {
            LicenseContent licenseContent = new LicenseContent();
            licenseContent.setHolder(DEFAULT_HOLDER_AND_ISSUER);
            licenseContent.setIssuer(DEFAULT_HOLDER_AND_ISSUER);
    
            licenseContent.setSubject(license.getSubject());
            licenseContent.setIssued(license.getIssuedTime());
            licenseContent.setNotBefore(license.getIssuedTime());
            licenseContent.setNotAfter(license.getExpiryTime());
            licenseContent.setConsumerType(license.getConsumerType());
            licenseContent.setConsumerAmount(license.getConsumerAmount());
            licenseContent.setInfo(license.getDescription());
    
            //扩展校验,这里可以自定义一些额外的校验信息(也可以用json字符串保存)
            if (license.getLicenseExtraModel() != null) {
                licenseContent.setExtra(license.getLicenseExtraModel());
            }
    
            return licenseContent;
        }
    
    }
    

    License信息

    @Data
    public class License implements Serializable {
    
        private static final long serialVersionUID = -7793154252684580872L;
    
        /**
         * 证书subject
         */
        private String subject;
    
        /**
         * 私钥别称
         */
        private String privateAlias;
    
        /**
         * 私钥密码(需要妥善保管,不能让使用者知道)
         */
        private String keyPass;
    
        /**
         * 访问私钥库的密码
         */
        private String storePass;
    
        /**
         * 证书生成路径
         */
        private String licensePath;
    
        /**
         * 私钥库存储路径
         */
        private String privateKeysStorePath;
    
        /**
         * 证书生效时间
         */
        private Date issuedTime = new Date();
    
        /**
         * 证书失效时间
         */
        private Date expiryTime;
    
        /**
         * 用户类型
         */
        private String consumerType = "user";
    
        /**
         * 用户数量
         */
        private Integer consumerAmount = 1;
    
        /**
         * 描述信息
         */
        private String description = "";
    
        /**
         * 额外的服务器硬件校验信息
         */
        private LicenseExtraModel licenseExtraModel;
    }
    

    LicenseExtraModel其它自定义的参数

    /**
     * 自定义需要校验的License参数,可以增加一些额外需要校验的参数,比如项目信息,ip地址信息等等,待完善
     */
    @Data
    public class LicenseExtraModel {
    
        // 这里可以添加一些往外的自定义信息,比如我们可以增加项目验证,客户电脑sn码的验证等等
        private Boolean flag;
    
    }
    

    生成license

    public static void main(String[] args) {
            // 生成license需要的一些参数
            License param = new License();
            // 证书授权主体
            param.setSubject("summit");
            // 私钥别名
            param.setPrivateAlias("privateKey");
            // 私钥密码(需要妥善保管,不能让使用者知道)
            param.setKeyPass("123456a");
            // 访问私钥库的密码
            param.setStorePass("123456a");
            // 证书存储地址
            param.setLicensePath("C:\\java-kaifa\\tongyu-workspace\\me\\springboot-jar\\my-stater\\src\\main\\resources\\license.lic");
            // 私钥库所在地址
            param.setPrivateKeysStorePath("C:\\java-kaifa\\tongyu-workspace\\me\\springboot-jar\\my-stater\\privateKeys.store");
            // 证书生效时间
            Calendar issueCalendar = Calendar.getInstance();
            param.setIssuedTime(issueCalendar.getTime());
            // 证书失效时间
            Calendar expiryCalendar = Calendar.getInstance();
            // 设置当前时间
            expiryCalendar.setTime(new Date());
            // 往后延长一年 = 授权一年时间
            expiryCalendar.add(Calendar.YEAR, 1);
            param.setExpiryTime(expiryCalendar.getTime());
            // 用户类型
            param.setConsumerType("user");
            // 用户数量
            param.setConsumerAmount(1);
            // 描述
            param.setDescription("测试");
    
            LicenseExtraModel model = new LicenseExtraModel();
            model.setFlag(true);
            param.setLicenseExtraModel(model);
            LicenseCreator licenseCreator = new LicenseCreator(param);
            // 生成license
            licenseCreator.generateLicense();
        }
    

    4.验证license

    public class LicenseVerify {
    
        private static Logger logger = LogManager.getLogger(LicenseVerify.class);
    
        /**
         * 证书subject
         */
        private String subject;
    
        /**
         * 公钥别称
         */
        private String publicAlias;
    
        /**
         * 访问公钥库的密码
         */
        private String storePass;
    
        /**
         * 证书生成路径
         */
        private String licensePath;
    
        /**
         * 密钥库存储路径
         */
        private String publicKeysStorePath;
    
        /**
         * LicenseManager
         */
        private LicenseManager licenseManager;
    
        /**
         * 额外参数
         */
        private LicenseExtraModel licenseExtraParam;
    
        public LicenseExtraModel getLicenseExtraParam() {
            return licenseExtraParam;
        }
    
        /**
         * 标识证书是否安装成功
         */
        private boolean installSuccess;
    
        public LicenseVerify(String subject, String publicAlias, String storePass, String licensePath, String publicKeysStorePath) {
            this.subject = subject;
            this.publicAlias = publicAlias;
            this.storePass = storePass;
            this.licensePath = licensePath;
            this.publicKeysStorePath = publicKeysStorePath;
        }
    
        /**
         * 安装License证书,读取证书相关的信息, 在bean加入容器的时候自动调用
         */
        public void installLicense() {
            try {
                Preferences preferences = Preferences.userNodeForPackage(LicenseVerify.class);
    
                CipherParam cipherParam = new DefaultCipherParam(storePass);
    
                KeyStoreParam publicStoreParam = new CustomKeyStoreParam(LicenseVerify.class,
                        publicKeysStorePath,
                        publicAlias,
                        storePass,
                        null);
                LicenseParam licenseParam = new DefaultLicenseParam(subject, preferences, publicStoreParam, cipherParam);
    
                licenseManager = new CustomLicenseManager(licenseParam);
                licenseManager.uninstall();
                LicenseContent licenseContent = licenseManager.install(new File(licensePath));
                licenseExtraParam = (LicenseExtraModel) licenseContent.getExtra();
    
                DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                installSuccess = true;
                logger.info("------------------------------- 证书安装成功 -------------------------------");
                logger.info(MessageFormat.format("证书有效期:{0} - {1}", format.format(licenseContent.getNotBefore()), format.format(licenseContent.getNotAfter())));
            } catch (Exception e) {
                installSuccess = false;
                logger.error("------------------------------- 证书安装失败 -------------------------------");
                logger.error(e);
            }
        }
    
        /**
         * 卸载证书,在bean从容器移除的时候自动调用
         */
        public void unInstallLicense() {
            if (installSuccess) {
                try {
                    licenseManager.uninstall();
                } catch (Exception e) {
                    // ignore
                }
            }
        }
    
        /**
         * 校验License证书
         */
        public boolean verify() {
            try {
                LicenseContent licenseContent = licenseManager.verify();
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    
    }
    

    测试

    public static void main(String[] args) {
            LicenseVerify licenseVerify = new LicenseVerify("summit", "publiccert", "123456b",
                    "C:\\java-kaifa\\tongyu-workspace\\me\\springboot-jar\\my-stater\\src\\main\\resources\\license.lic",
                    "C:\\java-kaifa\\tongyu-workspace\\me\\springboot-jar\\my-stater\\src\\main\\resources\\publicCerts.store"
            );
    
            licenseVerify.installLicense();
            licenseVerify.verify();
        }
    
    // 打印结果
    //> Task :my-stater:VerifyMain.main()
    //16:21:08.553 [main] INFO cn.summit.licence.comm.LicenseVerify - ------------------------------- 证书安装成功 -----------------
    //16:21:08.559 [main] INFO cn.summit.licence.comm.LicenseVerify - 证书有效期:2022-07-28 16:20:28 - 2023-07-28 16:20:28
    

    5.集合project

    代码见代码地址

    @Configuration
    public class LicenseConfig {
    
        @Bean(initMethod = "installLicense", destroyMethod = "unInstallLicense")
        public LicenseVerify licenseVerify() {
            return new LicenseVerify(subject, publicAlias, storePass, licensePath, publicKeysStorePath);
        }
    
        /**
         * 证书subject
         */
        @Value("${license.subject:summit}")
        private String subject;
    
        /**
         * 公钥别称
         */
        @Value("${license.publicAlias:publiccert}")
        private String publicAlias;
    
        /**
         * 访问公钥库的密码
         */
        @Value("${license.storePass:123456b}")
        private String storePass;
    
        /**
         * 证书生成路径
         */
        @Value("${license.licensePath:C:\\java-kaifa\\tongyu-workspace\\me\\springboot-jar\\my-stater\\src\\main\\resources\\license.lic}")
        private String licensePath;
    
        /**
         * 密钥库存储路径
         */
        @Value("${license.publicKeysStorePath:classpath:publicCerts.store}")
        private String publicKeysStorePath;
    
    
    }
    

    实际使用中可以将项目中一些参数放入LicenseExtraModel对象,在项目启动的时候控制一些业务上权限

    相关文章

      网友评论

          本文标题:1.使用license项目证书管理

          本文链接:https://www.haomeiwen.com/subject/tuexwrtx.html