13693261870
2024-12-30 edc9a6674eb9b40e33a74c5f022d279712ed3b7c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
package com.se.system.domain.vo;
 
import com.se.system.service.inte.IAServerInfoService;
import com.se.system.utils.*;
import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
 
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
 
@SuppressWarnings("ALL")
public class LicenseCustomMg extends LicenseManager {
    public LicenseCustomMg() {
    }
 
    /**
     * XML编码
     */
    private static final String XML_CHARSET = "UTF-8";
    /**
     * 默认BUFF_SIZE
     */
    private static final int DEFAULT_BUFF_SIZE = 8 * 1024;
 
    public LicenseCustomMg(LicenseParam param) {
        super(param);
    }
 
    /**
     * <p>重写LicenseManager的create方法</p>
     *
     * @param content LicenseContent 证书信息
     * @param notary  notary 公正信息
     * @return byte[]
     * @throws Exception 默认异常
     */
    @Override
    protected synchronized byte[] create(LicenseContent content, LicenseNotary notary) throws Exception {
        initialize(content);
        /** 加入自己额外的许可内容信息认证 == 主要友情提示 */
        this.validateCreate(content);
        final GenericCertificate certificate = notary.sign(content);
        return getPrivacyGuard().cert2key(certificate);
    }
 
 
    /**
     * <p>重写install方法</p>
     *
     * @param key    密匙
     * @param notary 公正信息
     * @return LicenseContent 证书信息
     * @throws Exception 默认异常
     */
    @Override
    protected synchronized LicenseContent install(final byte[] key, final LicenseNotary notary) throws Exception {
        final GenericCertificate certificate = getPrivacyGuard().key2cert(key);
        notary.verify(certificate);
        final LicenseContent licenseContent = (LicenseContent) this.load(certificate.getEncoded());
        /** 增加额外的自己的license校验方法,校验ip、mac、cpu序列号等 */
        this.validate(licenseContent);
        setLicenseKey(key);
        setCertificate(certificate);
        return licenseContent;
    }
 
    /**
     * <p>重写verify方法</p>
     *
     * @param notary 公正信息
     * @return LicenseContent 证书信息
     * @throws Exception 默认异常
     */
    @Override
    protected synchronized LicenseContent verify(final LicenseNotary notary) throws Exception {
        final byte[] key = getLicenseKey();
        if (null == key) {
            throw new NoLicenseInstalledException(getLicenseParam().getSubject());
        }
        GenericCertificate certificate = getPrivacyGuard().key2cert(key);
        notary.verify(certificate);
        final LicenseContent content = (LicenseContent) this.load(certificate.getEncoded());
        /** 增加额外的自己的license校验方法,校验ip、mac、cpu序列号等 */
        this.validate(content);
        setCertificate(certificate);
        return content;
    }
 
    /**
     * <p>校验生成证书的参数信息</p>
     *
     * @param content LicenseContent 证书内容
     * @throws LicenseContentException 证书内容错误异常
     */
    protected synchronized void validateCreate(final LicenseContent content) throws LicenseContentException {
        // 当前时间
        final Date now = new Date();
        // 生效时间
        final Date notBefore = content.getNotBefore();
        // 失效时间
        final Date notAfter = content.getNotAfter();
 
        if (null != notAfter && now.after(notAfter)) {
            String message = "证书失效时间不能早于当前时间";
            System.out.println("message = " + message);
            throw new LicenseContentException(message);
        }
        if (null != notBefore && null != notAfter && notAfter.before(notBefore)) {
            String message = "证书生效时间不能晚于证书失效时间";
            System.out.println("message = " + message);
            throw new LicenseContentException(message);
        }
        final String consumerType = content.getConsumerType();
        if (null == consumerType) {
            String message = "用户类型不能为空";
            System.out.println("message = " + message);
            throw new LicenseContentException(message);
        }
 
    }
 
    /**
     * <p>重写validate方法,增加ip地址、mac地址、cpu序列号等其他信息的校验</p>
     *
     * @param content LicenseContent 证书内容
     * @throws LicenseContentException 证书内容错误异常
     */
    @Override
    protected synchronized void validate(final LicenseContent content) throws LicenseContentException {
        // 当前时间
        final Date now = new Date();
        final Date notAfter = content.getNotAfter();
        if (now.after(notAfter)) {
            throw new LicenseContentException("系统证书过期,当前时间已超过证书有效期 -- " +
                    DateUtils.date2Str(content.getNotAfter()) + "");
        }
        // 1、 首先调用父类的validate方法
        super.validate(content);
        // 2、 然后校验自定义的License参数 License中可被允许的参数信息
        LicenseExtraParamVo expectedCheck = (LicenseExtraParamVo) content.getExtra();
        // 当前服务器真实的参数信息
        LicenseExtraParamVo serverCheckModel = IAServerInfoService.getServer(null).getServerInfos();
        if (expectedCheck != null && serverCheckModel != null) {
            // 校验IP地址
            if (expectedCheck.isIpCheck() && !checkIpAddress(expectedCheck.getIpAddress(), serverCheckModel.getIpAddress())) {
                String message = "系统证书无效,当前服务器的IP没在授权范围内";
                System.out.println("message = " + message);
                throw new LicenseContentException(message);
            }
            // 校验Mac地址
            if (expectedCheck.isMacCheck() && !checkIpAddress(expectedCheck.getMacAddress(), serverCheckModel.getMacAddress())) {
                String message = "系统证书无效,当前服务器的Mac地址没在授权范围内";
                System.out.println("message = " + message);
                throw new LicenseContentException(message);
            }
            // 校验主板序列号
            if (expectedCheck.isBoardCheck() && !checkSerial(expectedCheck.getMainBoardSerial(), serverCheckModel.getMainBoardSerial())) {
                String message = "系统证书无效,当前服务器的主板序列号没在授权范围内";
                System.out.println("message = " + message);
                throw new LicenseContentException(message);
            }
            // 校验CPU序列号
            if (expectedCheck.isCpuCheck() && !checkSerial(expectedCheck.getCpuSerial(), serverCheckModel.getCpuSerial())) {
                String message = "系统证书无效,当前服务器的CPU序列号没在授权范围内";
                System.out.println("message = " + message);
                throw new LicenseContentException(message);
            }
        } else {
            System.out.println("不能获取服务器硬件信息");
            throw new LicenseContentException("不能获取服务器硬件信息");
        }
    }
 
    /**
     * <p>重写XMLDecoder解析XML</p>
     */
    private Object load(String encoded) {
        BufferedInputStream inputStream = null;
        XMLDecoder decoder = null;
        try {
            inputStream = new BufferedInputStream(new ByteArrayInputStream(encoded.getBytes(XML_CHARSET)));
            decoder = new XMLDecoder(new BufferedInputStream(inputStream, DEFAULT_BUFF_SIZE), null, null);
            return decoder.readObject();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } finally {
            try {
                if (decoder != null) {
                    decoder.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                System.out.println("XMLDecoder解析XML失败 ");
                e.printStackTrace();
            }
        }
        return null;
 
    }
 
    /**
     * 校验当前服务器的IP/Mac地址是否在可被允许的IP范围内<br/>
     * 如果存在IP在可被允许的IP/Mac地址范围内,则返回true
     */
    private boolean checkIpAddress(List<String> expectedList, List<String> serverList) {
 
        /** 如果期望的IP列表空直接返回false,因为既然验证ip,这一项必须要有元素 */
        if (CommonUtils.isEmpty(expectedList)) {
            return false;
        }
        /** 如果当前服务器的IP列表空直接返回false,因为服务器不可能获取不到ip,没有的话验证个锤子 */
        if (CommonUtils.isEmpty(serverList)) {
            return false;
        }
        for (String expected : expectedList) {
            if (serverList.contains(expected.trim())) {
                return true;
            }
        }
        return false;
 
    }
 
    /**
     * <p>校验当前服务器硬件(主板、CPU等)序列号是否在可允许范围内</p>
     *
     * @param expectedSerial 主板信息
     * @param serverSerial   服务器信息
     * @return boolean
     */
    private boolean checkSerial(String expectedSerial, String serverSerial) {
        if (CommonUtils.isNotEmpty(expectedSerial)) {
            if (CommonUtils.isNotEmpty(serverSerial)) {
                return expectedSerial.equals(serverSerial);
            }
            return false;
        } else {
            return true;
        }
    }
}