liusuyi
2026-05-30 f4f4fc53260eb67483dce406a963628273786a61
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
package com.ard.work.sdk.zlxd.service;
 
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
/**
 * 中林信达加密策略
 *
 * @author 刘苏义
 * @since 2023-11-07
 */
public final class ZlxdLoginEncryptor {
 
    private static final String FIXED_SALT = "PreLogin:PreLogin";
 
    private ZlxdLoginEncryptor() {
        // 工具类不允许实例化
    }
 
    /**
     * 生成登录加密摘要
     *
     * @param username  用户名
     * @param password  密码
     * @param sessionId 会话ID(PreLogin 返回)
     * @param challenge 随机挑战码(PreLogin 返回)
     * @return 加密后的字符串(MD5),参数不完整返回 null
     */
    public static String encrypt(
            String username,
            String password,
            String sessionId,
            String challenge
    ) {
        if (isBlank(username) || isBlank(password)
                || isBlank(sessionId) || isBlank(challenge)) {
            return null;
        }
 
        // step1: MD5(username:sessionId:password)
        String step1Plain = username + ":" + sessionId + ":" + password;
        String step1Hash = md5(step1Plain);
 
        // step2: MD5("PreLogin:PreLogin")
        String salt = md5(FIXED_SALT);
 
        // step3: MD5(step1Hash:challenge:salt)
        String finalPlain = step1Hash + ":" + challenge + ":" + salt;
        return md5(finalPlain);
    }
 
    private static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
 
            // 保持和 BigInteger.toString(16) 行为一致(不补0)
            return new BigInteger(1, digest).toString(16);
        } catch (Exception e) {
            throw new RuntimeException("MD5 encrypt error", e);
        }
    }
 
    private static boolean isBlank(String s) {
        return s == null || s.trim().isEmpty();
    }
}