Administrator
15 hours ago 6a51f45e6a00b65a9e7b0b0707b453c11311f3ef
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
package com.xcong.excoin.modules.okxApi;
 
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Random;
 
/**
 * OKX API 工具类:SSL配置、HMAC-SHA256签名、订单ID生成、日期格式化、JSON构建。
 *
 * @author Administrator
 */
@Slf4j
public final class OkxWsUtil {
 
    private OkxWsUtil() {}
 
    // ==================== SSL ====================
 
    public static void configureSSL() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
                        @Override
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                        @Override
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                    }
            };
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new SecureRandom());
            SSLContext.setDefault(sc);
        } catch (Exception e) {
            log.error("SSL配置失败", e);
        }
    }
 
    // ==================== HMAC-SHA256 签名 ====================
 
    public static String signWebsocket(String timestamp, String secretKey) {
        return sign(timestamp, "GET", "/users/self/verify", "", secretKey);
    }
 
    public static String signRest(String timestamp, String method, String path, String body, String secretKey) {
        return sign(timestamp, method.toUpperCase(), path, body, secretKey);
    }
 
    private static String sign(String timestamp, String method, String path, String body, String secretKey) {
        try {
            String message = String.format("%s%s%s%s", timestamp, method, path, body);
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec spec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
            mac.init(spec);
            byte[] hash = mac.doFinal(message.getBytes("UTF-8"));
            return Base64.getEncoder().encodeToString(hash);
        } catch (Exception e) {
            log.error("签名计算失败", e);
            return "";
        }
    }
 
    // ==================== 订单ID ====================
 
    private static final ThreadLocal<SimpleDateFormat> ORDER_ID_DF =
            ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss"));
 
    private static final ThreadLocal<Random> RANDOM =
            ThreadLocal.withInitial(Random::new);
 
    public static String getOrderNum(String prefix) {
        String dd = ORDER_ID_DF.get().format(new Date());
        if (prefix != null && !prefix.isEmpty()) {
            return prefix + dd + getRandomNum(5);
        }
        return dd + getRandomNum(5);
    }
 
    private static String getRandomNum(int length) {
        String str = "0123456789";
        Random random = RANDOM.get();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; ++i) {
            sb.append(str.charAt(random.nextInt(str.length())));
        }
        return sb.toString();
    }
 
    // ==================== JSON构建 ====================
 
    public static JSONObject buildJsonObject(String connId, String op, JSONArray args) {
        JSONObject jsonObject = new JSONObject();
        if (connId != null && !connId.isEmpty()) {
            jsonObject.put("id", connId);
        }
        jsonObject.put("op", op);
        jsonObject.put("args", args);
        return jsonObject;
    }
 
    // ==================== 日期格式化 ====================
 
    private static final ThreadLocal<SimpleDateFormat> DATE_TIME_DF =
            ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
 
    private static final ThreadLocal<SimpleDateFormat> ISO8601_DF =
            ThreadLocal.withInitial(() -> {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                sdf.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
                return sdf;
            });
 
    public static String getIso8601Timestamp() {
        return ISO8601_DF.get().format(new Date());
    }
 
    public static String timestampToDateTime(long timestamp) {
        return DATE_TIME_DF.get().format(new Date(timestamp));
    }
}