xuekang
2024-05-11 bac0878349a1db23e7b420ea164e22fb9db73a99
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
package com.nuvole.hnnx.conf;
 
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.Method;
import com.nuvole.hnnx.hnnxPay.HnnxConstant;
import com.nuvole.hnnx.hnnxPay.KeyMetadata;
import com.nuvole.hnnx.hnnxPay.KeyRegistry;
import com.nuvole.hnnx.hnnxPay.KeyRegistryImpl;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
 
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
/**
 * @ClassName NxPayConfig
 * @Author cy
 * @Date 2023/10/5
 * @Description
 * @Version 1.0
 **/
//@ConditionalOnProperty(name = "offLinePay.hnnx", havingValue = "true")
@Data
@PropertySource("classpath:hnnx.properties")
@ConfigurationProperties(prefix = "hnnx")
@Component
public class NxPayConfig {
    private String merNbr;
    private String url;
    private String appCode;
    private String certPath;
    private String certPwd;
    private String pubKey;
    private String platSubMerchantId;
    private String branchId;
    public static final String KEYSTORE_TYPE = "PKCS12"; // 私钥类型
//    private static String keyPath = "C:\\Users\\cy\\Desktop\\merchant-rsa.pfx"; // 私钥容器路径
//    private static String cardPwdAlias = "HNNX"; // 私钥证书别名
    /**
     * 快捷支付公钥
     */
    private String kjUrl;
    private String kjMerNbr;
 
    @Bean(name = "nxPayPrivateKey")
    public PrivateKey payPrivateKey() {
        KeyRegistry keyRegistry = new KeyRegistryImpl();
        KeyMetadata keyMetadata = new KeyMetadata("nxPay", certPath, certPwd, null, certPwd);
        System.out.println(keyMetadata);
        Key privatekey = keyRegistry.getKey(keyMetadata);
        System.out.println(privatekey);
        return (PrivateKey) privatekey;
    }
 
    @Bean(name = "nxPayPublicKey")
    public PublicKey payPublicKey() {
        BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(("-----BEGIN CERTIFICATE-----\n" + pubKey + "\n-----END CERTIFICATE-----\n").getBytes()));
        Certificate certificate = null;
        CertificateFactory cf = null;
        try {
            cf = CertificateFactory.getInstance("X.509");
            certificate = cf.generateCertificate(bis);
            return certificate.getPublicKey();
        } catch (CertificateException e) {
            e.printStackTrace();
        }
        return null;
    }
    private String kjPubKey;
    private String kjCertPath;
    private String kjCertPwd;
    private String kjPlatSubMerchantId;
 
//    public static void main(String[] args) throws Exception {
//        InputStream key = new FileInputStream(keyPath);
//        KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
//        ks.load(key, cardPwdAlias.toCharArray());
//        Enumeration<String> keyAlias = ks.aliases();
//        PrivateKey privateKey = null;
//        while (keyAlias.hasMoreElements()) {
//            String nextElement = keyAlias.nextElement();
//            boolean keyEntryFlag = ks.isKeyEntry(nextElement);
//            if (keyEntryFlag) {
//                privateKey = (PrivateKey) ks.getKey(nextElement, cardPwdAlias.toCharArray());
//                break;
//            }
//        }
//
//
//    }
 
    @Bean(name = "nxKjPayPrivateKey")
    public PrivateKey nxKjPayPrivateKey() throws Exception {
        KeyRegistry keyRegistry = new KeyRegistryImpl();
        KeyMetadata keyMetadata = new KeyMetadata("nxKjPay", kjCertPath,  kjCertPwd, null,  kjCertPwd);
        Key privatekey = keyRegistry.getKey(keyMetadata);
        return (PrivateKey) privatekey;
//        InputStream key = new FileInputStream(keyPath);
//        KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
//        ks.load(key, cardPwdAlias.toCharArray());
//        Enumeration<String> keyAlias = ks.aliases();
//        PrivateKey privateKey = null;
//        while (keyAlias.hasMoreElements()) {
//            String nextElement = keyAlias.nextElement();
//            boolean keyEntryFlag = ks.isKeyEntry(nextElement);
//            if (keyEntryFlag) {
//                privateKey = (PrivateKey) ks.getKey(nextElement, cardPwdAlias.toCharArray());
//                break;
//            }
//        }
//        return privateKey;
 
    }
 
    @Bean(name = "nxKjPayPublicKey")
    public PublicKey nxKjPayPublicKey() {
        BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(("-----BEGIN CERTIFICATE-----\n" + kjPubKey + "\n-----END CERTIFICATE-----\n").getBytes()));
        Certificate certificate = null;
        CertificateFactory cf = null;
        try {
            cf = CertificateFactory.getInstance("X.509");
            certificate = cf.generateCertificate(bis);
            return certificate.getPublicKey();
        } catch (CertificateException e) {
            e.printStackTrace();
        }
        return null;
    }
 
 
    //    @Bean(name = "nxPayHttpClient")
    public HttpRequest getPayCloseableHttpClient() {
        HttpRequest postRequest = new HttpRequest(url).method(Method.POST);
        String charset = CharsetUtil.CHARSET_UTF_8.toString();
        postRequest.header("appCode", appCode);
        postRequest.header("version", "1.0");
        postRequest.header("charset", charset);
        postRequest.header("algorithm", HnnxConstant.ALGORITHM);
        postRequest.header("deviceId", HnnxConstant.DEVICEID);
        postRequest.header("channelId", HnnxConstant.CHANNELID);
        postRequest.header("sequenceId", getSequenceId());
        return postRequest;
    }
 
    /**
     * 请求序列号【渠道端产生,一笔业务的唯一标识,贯穿整个交易始终】渠道代码(2位)+日期(yyMMdd 6位)+流水号(24位,appCode+剩余位数流水号)
     *
     * @return
     */
    private String getSequenceId() {
        StringBuilder sequenceIdSb = new StringBuilder();
        sequenceIdSb.append(HnnxConstant.CHANNELID)
                .append(DateUtil.format(new Date(), FastDateFormat.getInstance("yyMMdd")))
                .append(appCode);
        int length = 32 - sequenceIdSb.length();
 
        String timeTemp = System.currentTimeMillis() + "";
        while (length > 0) {
            if (length > timeTemp.length()) {
                sequenceIdSb.append(timeTemp);
            } else {
                sequenceIdSb.append(timeTemp.substring(0, length));
            }
            length = 32 - sequenceIdSb.length();
        }
        return sequenceIdSb.toString();
    }
 
    public Map getHeadMap(String sequenceId, String timestamp, String branchId) {
        Map headMap = new HashMap<>();
        String charset = CharsetUtil.CHARSET_UTF_8.toString();
        headMap.put("appCode", appCode);
        headMap.put("version", "1.0");
        headMap.put("charset", charset);
        headMap.put("algorithm", HnnxConstant.ALGORITHM);
        headMap.put("deviceId", HnnxConstant.DEVICEID);
        headMap.put("channelId", HnnxConstant.CHANNELID);
        headMap.put("sequenceId", sequenceId);
        headMap.put("timestamp", timestamp);
//        headMap.put("transCode", transCode);
        headMap.put("branchId", branchId);
        return headMap;
    }
}