Java 语言奇亚(Chia, XCH) 接口之获取主链相关信息(含最新块高) - 自签名证书双向验证

yufei       3 年, 6 月 前       915

关于如何使用 curl 命令来获取奇亚(Chia, XCH) 接口之获取主链相关信息(含最新块高),请移步 https://www.twle.cn/t/19316#reply0

这里只贴上 Java 使用 HttpsURLConnection 来实现的版本

首先生成证书

生成证书要经过两个 shell 命令

.crt.key 导出为 server.p12

openssl pkcs12 -export -in ~/.chia/mainnet/config/ssl/full_node/private_full_node.crt -inkey ~/.chia/mainnet/config/ssl/full_node/private_full_node.key -password pass:110220 -name localhost -out server.p12 

.p12 导出为 .jks

keytool -importkeystore -srckeystore server.p12 -destkeystore keystore.jks -srcstoretype pkcs12 -deststoretype jks -deststorepass 110220 -srcstorepass 110220 -deststoretype pkcs12

其次解释下几个要点

  1. 忽略证书验证
X509TrustManager x509m = new X509TrustManager() {
    //返回受信任的X509证书数组。
    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
    // 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。
    //在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    // 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,
    //因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
};

SSLContext sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(kmf.getKeyManagers(), new TrustManager[]{x509m},null);
  1. 忽略域名和证书的匹配
// 不检查域名和证书是否配对
HostnameVerifier allHostsValid = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
  1. 添加自签名的证书
// keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/Users/yufei/Downloads/thsh/keystore.jks"),"110220".toCharArray());
KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509", "SunJSSE");  
kmf.init(ks,"110220".toCharArray());  

全部代码如下

package thsh;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.HostnameVerifier;
import java.io.IOException;
import java.net.URL;


public class App {


    public static void main(String[] args) throws Exception{

        // keystore
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(new FileInputStream("/Users/yufei/Downloads/thsh/keystore.jks"),"110220".toCharArray());
        KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509", "SunJSSE");  
        kmf.init(ks,"110220".toCharArray());  


        String posted = "{}";


        X509TrustManager x509m = new X509TrustManager() {
            //返回受信任的X509证书数组。
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            // 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。
            //在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            // 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,
            //因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
        };

        SSLContext sslcontext = SSLContext.getInstance("SSL");
        sslcontext.init(kmf.getKeyManagers(), new TrustManager[]{x509m},null);

        // 不检查域名和证书是否配对
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);


        URL serverUrl = new URL("https://localhost:8555/get_blockchain_state");
        HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();
        conn.setSSLSocketFactory(sslcontext.getSocketFactory());
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; utf-8");
        conn.setRequestProperty("Accept", "application/json");
        //必须设置false,否则会自动redirect到重定向后的地址
        conn.setInstanceFollowRedirects(false);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        try(OutputStream os = conn.getOutputStream()) {
            byte[] input = posted.getBytes("utf-8");
            os.write(input, 0, input.length);           
        }

        conn.connect();
        String result = getReturn(conn);
        System.out.println(result);
    }

    /*请求url获取返回的内容*/
    public static String getReturn(HttpsURLConnection connection) throws IOException{
        StringBuffer buffer = new StringBuffer();
        //将返回的输入流转换成字符串
        try(InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            String result = buffer.toString();
            return result;
        }
    }
}

输出结果如下

{"blockchain_state": {"difficulty": 1056, "genesis_challenge_initialized": true, "mempool_size": 10, "peak": {"challenge_block_info_hash": "0x9f16cd40f3520633550a8c6b3ed2f1763e4b7524835bc7fce7abdd8e8c3fbf04", "challenge_vdf_output": {"data": "0x00005d62f70f96305e7bf18987b6c2fdd39c54d4df25754cdad364bffc4bd267e4d7e9e799e965c0cdc01845a802da4177f955ce0aca52da0fcf6f1695c148e107052a24d766c33e37edbe8abb9c6195c6d59187674b97a5424144bdf05df0a7a1050100"}, "deficit": 0, "farmer_puzzle_hash": "0xd7fa58bf5fdef6063622e391b1a6e27bba83f4a93388166909fe7e882a7a5e22", "fees": null, "finished_challenge_slot_hashes": null, "finished_infused_challenge_slot_hashes": null, "finished_reward_slot_hashes": null, "header_hash": "0xd9683002e5a3681cad6927187796901b3af6f54befb6d7e5a2f5927fc033b8e3", "height": 371692, "infused_challenge_vdf_output": {"data": "0x030020d0308f0dcf12ea4d6c5d9fd9e18db7b7326875eba14b42ca4b9f72ca112927bb78e99f1eeb50c2679ad0283e9a447c190e5af7ecb58031d95413e191a253462fa3228ad81d57d353982b999b4f11a03edc4922bb3d987d8d7aa9af5e9a46030100"}, "overflow": false, "pool_puzzle_hash": "0xd7fa58bf5fdef6063622e391b1a6e27bba83f4a93388166909fe7e882a7a5e22", "prev_hash": "0x437f692f17a4257a8b878f0e0bb2a80380da0bd7996a5eebf85dec56dd264eed", "prev_transaction_block_hash": null, "prev_transaction_block_height": 371690, "required_iters": 142434, "reward_claims_incorporated": null, "reward_infusion_new_challenge": "0x7bc5bcb109c66e2ec68e4d9bdfb15ba10b2e43de96bff0f67a406900f615e9aa", "signage_point_index": 45, "sub_epoch_summary_included": null, "sub_slot_iters": 111673344, "timestamp": null, "total_iters": 1209271856226, "weight": 77768896}, "space": 17964932862054492160, "sub_slot_iters": 111673344, "sync": {"sync_mode": false, "sync_progress_height": 0, "sync_tip_height": 0, "synced": true}}, "success": true}
目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.