chengkun
2025-06-05 4080b5997b38ca84b3b203c7101dcadb97b76925
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
/**
 * Alipay.com Inc. Copyright (c) 2004-2020 All Rights Reserved.
 */
package com.alipay.easysdk.kernel;
 
import com.alipay.easysdk.kernel.util.AntCertificationUtil;
import com.google.common.base.Strings;
 
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * 证书模式运行时环境
 *
 * @author zhongyu
 * @version $Id: CertEnvironment.java, v 0.1 2020年01月02日 5:21 PM zhongyu Exp $
 */
public class CertEnvironment {
    /**
     * 支付宝根证书内容
     */
    private String rootCertContent;
 
    /**
     * 支付宝根证书序列号
     */
    private String rootCertSN;
 
    /**
     * 商户应用公钥证书序列号
     */
    private String merchantCertSN;
 
    /**
     * 缓存的不同支付宝公钥证书序列号对应的支付宝公钥
     */
    private Map<String, String> cachedAlipayPublicKey = new ConcurrentHashMap<String, String>();
 
    /**
     * 构造证书运行环境
     *
     * @param merchantCertPath   商户公钥证书路径
     * @param alipayCertPath     支付宝公钥证书路径
     * @param alipayRootCertPath 支付宝根证书路径
     */
    public CertEnvironment(String merchantCertPath, String alipayCertPath, String alipayRootCertPath) {
        if (Strings.isNullOrEmpty(merchantCertPath) || Strings.isNullOrEmpty(alipayCertPath) || Strings.isNullOrEmpty(alipayCertPath)) {
            throw new RuntimeException("证书参数merchantCertPath、alipayCertPath或alipayRootCertPath设置不完整。");
        }
 
        this.rootCertContent = AntCertificationUtil.readCertContent(alipayRootCertPath);
        this.rootCertSN = AntCertificationUtil.getRootCertSN(rootCertContent);
        this.merchantCertSN = AntCertificationUtil.getCertSN(AntCertificationUtil.readCertContent((merchantCertPath)));
 
        String alipayPublicCertContent = AntCertificationUtil.readCertContent(alipayCertPath);
        cachedAlipayPublicKey.put(AntCertificationUtil.getCertSN(alipayPublicCertContent),
                AntCertificationUtil.getCertPublicKey(alipayPublicCertContent));
    }
 
    public String getRootCertSN() {
        return rootCertSN;
    }
 
    public String getMerchantCertSN() {
        return merchantCertSN;
    }
 
    public String getAlipayPublicKey(String sn) {
        //如果没有指定sn,则默认取缓存中的第一个值
        if (Strings.isNullOrEmpty(sn)) {
            return cachedAlipayPublicKey.values().iterator().next();
        }
 
        if (cachedAlipayPublicKey.containsKey(sn)) {
            return cachedAlipayPublicKey.get(sn);
        } else {
            //网关在支付宝公钥证书变更前,一定会确认通知到商户并在商户做出反馈后,才会更新该商户的支付宝公钥证书
            //TODO: 后续可以考虑加入自动升级支付宝公钥证书逻辑,注意并发更新冲突问题
            throw new RuntimeException("支付宝公钥证书[" + sn + "]已过期,请重新下载最新支付宝公钥证书并替换原证书文件");
        }
    }
}