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
工作流程:
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简单介绍下 ,希望对小伙伴有帮助.