webservice的客户端,服务端实现和调用本质上是http发布和调用

1.证书文件符合要求的标准pem,如果是java 的keystore或者其他格式,首先转为pfx,然后再生成对应的 pub_cert,private_key

java实现keystore转为pfx格式:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Enumeration;

public class KeyStoreTopfx {

    public static final String PKCS12 = "PKCS12";
    public static final String JKS = "JKS";
    public static final String PFX_KEYSTORE_FILE = "D:\\123.pfx";
    public static final String KEYSTORE_PASSWORD = "pwd3456";
    public static final String JKS_KEYSTORE_FILE = "D:\\123.keystore";

    /**
     * 将pfx或p12的文件转为keystore
     */
    public static void coverTokeyStore() {
        try {
            KeyStore inputKeyStore = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(PFX_KEYSTORE_FILE);
            char[] nPassword = null;

            if ((KEYSTORE_PASSWORD == null)
                    || KEYSTORE_PASSWORD.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = KEYSTORE_PASSWORD.toCharArray();
            }

            inputKeyStore.load(fis, nPassword);
            fis.close();

            KeyStore outputKeyStore = KeyStore.getInstance("JKS");

            outputKeyStore.load(null, KEYSTORE_PASSWORD.toCharArray());

            Enumeration enums = inputKeyStore.aliases();

            while (enums.hasMoreElements()) { // we are readin just one
                // certificate.

                String keyAlias = (String) enums.nextElement();

                System.out.println("alias=[" + keyAlias + "]");

                if (inputKeyStore.isKeyEntry(keyAlias)) {
                    Key key = inputKeyStore.getKey(keyAlias, nPassword);
                    Certificate[] certChain = inputKeyStore
                            .getCertificateChain(keyAlias);

                    outputKeyStore.setKeyEntry(keyAlias, key,
                            KEYSTORE_PASSWORD.toCharArray(), certChain);
                }
            }

            FileOutputStream out = new FileOutputStream(JKS_KEYSTORE_FILE);

            outputKeyStore.store(out, nPassword);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 将keystore转为pfx
     */
    public static void coverToPfx() {
        try {
            KeyStore inputKeyStore = KeyStore.getInstance("JKS");
            FileInputStream fis = new FileInputStream(JKS_KEYSTORE_FILE);
            char[] nPassword = null;

            if ((KEYSTORE_PASSWORD == null)
                    || KEYSTORE_PASSWORD.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = KEYSTORE_PASSWORD.toCharArray();
            }

            inputKeyStore.load(fis, nPassword);
            fis.close();

            KeyStore outputKeyStore = KeyStore.getInstance("PKCS12");

            outputKeyStore.load(null, KEYSTORE_PASSWORD.toCharArray());

            Enumeration enums = inputKeyStore.aliases();

            while (enums.hasMoreElements()) { // we are readin just one
                // certificate.

                String keyAlias = (String) enums.nextElement();

                System.out.println("alias=[" + keyAlias + "]");

                if (inputKeyStore.isKeyEntry(keyAlias)) {
                    Key key = inputKeyStore.getKey(keyAlias, nPassword);
                    Certificate[] certChain = inputKeyStore
                            .getCertificateChain(keyAlias);

                    outputKeyStore.setKeyEntry(keyAlias, key,
                            KEYSTORE_PASSWORD.toCharArray(), certChain);
                }
            }

            FileOutputStream out = new FileOutputStream(PFX_KEYSTORE_FILE);

            outputKeyStore.store(out, nPassword);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        coverToPfx();
    }


}

//对pfx进行转换,生成标准pem文件,在linux中顺序执行以下命令

1.openssl pkcs12 -in server.pfx -nodes -out server.pem

2.openssl rsa -in server.pem -out server.key

3.openssl x509 -in server.pem -out server.crt

2.对https原理的简单介绍

首先必须对http协议比较熟悉和了解,最好是自己用golang实现webservice的http的客户端,这样会更容易理解https协议和数据通信过程

HTTPS = HTTP + TLS/SSL

preview

工作流程:

3.golang实现https调用服务器端webserice

 思路和实现http是一样的原理,只是在多了SSL证书的处理上有区别.

(一)生成httpsclient

func NewHttpsClient(clientCertPath, clientKeyPath string) *http.Client {
    tlsConfig := &tls.Config{InsecureSkipVerify: true}
    if clientCertPath != "" && clientKeyPath != "" {
        //clientCertPath:公钥  clientKeyPath私钥,也可以直接使用tls中的X509KeyPair,X509KeyPair需要两个[]byte参数可以init
        //保存到内存中,不用频繁读取
        clientCert, err := tls.LoadX509KeyPair(clientCertPath, clientKeyPath)
        if err != nil {
            log.Fatalln("Failed to load x509 client key pair:", err)
        }
        tlsConfig.Certificates = []tls.Certificate{clientCert}
        tlsConfig.Renegotiation = tls.RenegotiateFreelyAsClient
    } else if clientCertPath == "" && clientKeyPath != "" {
        log.Fatalln("Certificate file is required when using key file")
    } else if clientCertPath != "" && clientKeyPath == "" {
        log.Fatalln("Key file is required when using certificate file")
    }
    defaultTransport := http.DefaultTransport.(*http.Transport)
    transport := &http.Transport{
        Proxy:                 defaultTransport.Proxy,
        DialContext:           defaultTransport.DialContext,
        MaxIdleConns:          defaultTransport.MaxIdleConns,
        IdleConnTimeout:       defaultTransport.IdleConnTimeout,
        ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
        TLSHandshakeTimeout:   defaultTransport.TLSHandshakeTimeout,
        TLSClientConfig:       tlsConfig,
    }
    return &http.Client{Transport: transport}
}

(二)http请求出client替换为https的cliet,具体细节可以查看http/net的&http.Transport用法这里不再详细介绍

    //定义client,普通的是http,tls 为true是为https
    var client *http.Client
    if s.tls {
        client = newHttpsClient(s.clientCertPath, s.clientKeyPath)
    } else {
        tr := &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: s.tls,
            },
            Dial: dialTimeout,
        }
        client = &http.Client{Transport: tr}
    }
    res, err := client.Do(req)
    if err != nil {
        return err
    }
    defer res.Body.Close()

(三)请求soap的组装,根据wsdl需要的具体格式,自己组装数据,生成符合格式的soap-xml信息.

  soap的组装数据格式一定要正确

  •text/xml 这是基于soap1.1协议。

  •application/soap+xml 这是基于soap1.2协议。

  一定要保证协议的版本要正确,否则双方虽然能够正常通信,但是接收数据是有问题的.

golang中实现webservice的调用,实现的idea简单介绍下 ,希望对小伙伴有帮助.