基于CFCA证书的https请求示例(Java)

2020年05月24日,金融行业CFCA认证调用银行api接口

Posted by dafei on May 24, 2020

基于CFCA证书的https请求示例(Java)


背景

最近帮朋友处理一个与银行对接的接口,查询银行审批结果信息。用到了CFCA证书进行https请求的认证,要求使用pkcs7方式进行签名,银行提供签名Demo是Java,因此使用Java语言搭建了spring-mvc小型服务,提供API接口。
如下给出https请求示例,Java语言实现,供大家参考。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.*;

public class HttpsUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpsUtil.class);

    public static String send_https(String url_str, String parms, String pfxPath, String password) throws Exception {
        String sign = SignUtil.get_sign(parms, pfxPath, password); //获取签名
        logger.info("send_https, sign:" + sign);
        KeyStore clientStore = KeyStore.getInstance("PKCS12");
        clientStore.load(new FileInputStream(new File(pfxPath)), password.toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(clientStore, password.toCharArray());
        KeyManager[] kms = kmf.getKeyManagers();

        // Assuming that you imported the CA Cert "Subject: CN=MBIIS CA, OU=MBIIS, O=DAIMLER, C=DE"
        // to your cacerts Store.
        KeyStore trustStore = KeyStore.getInstance("JKS");
        trustStore.load(new FileInputStream("/jdk1.8/jre/lib/security/cacerts"), "changeit".toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
        TrustManager[] tms = tmf.getTrustManagers();

        final SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); // TLS
        sslContext.init(kms,tms,new SecureRandom());
        SSLContext.setDefault(sslContext);

        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        });

        URL url = new URL(url_str); // "https://***/abc.tav"

        byte[] out = parms.getBytes(StandardCharsets.UTF_8);
        int length = out.length;

        HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
        con.setRequestMethod("POST");
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setRequestProperty("Content-type", "application/json; charset=UTF-8");
        con.setFixedLengthStreamingMode(length);
        con.setRequestProperty("signdate", sign); //设置请求签名
        con.setConnectTimeout(100000);
        con.setSSLSocketFactory(sslContext.getSocketFactory());
        con.connect();

        OutputStream os = con.getOutputStream();
        os.write(out);
        os.close();

        int code= con.getResponseCode();
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line+"\n");
        }
        br.close();
        logger.info("send_https, code:" + code+ "\nresponse:" + sb.toString());
        return sb.toString();
    }

}