zoukankan      html  css  js  c++  java
  • 使用poco 的NetSSL_OpenSSL 搭建https 服务端,使用C++客户端,java 客户端访问,python访问(python还没找到带证书访问的代码.)

    V20161028

    由于项目原因,需要用到https去做一些事情.

    这儿做了一些相应的研究.

    这个https 用起来也是折腾人,还是研究了一周多+之前的一些积累.

    目录

    1,java client 通过https访问 C++ 的https server

    2,python client 通过https访问 C++ 的https server

    3,C++ 的https server 搭建.

    1,java client 通过https访问 C++ 的https server

    ///
    //参考代码:
    //http://blog.csdn.net/sunny243788557/article/details/38874153
    //http://ln-ydc.iteye.com/blog/1335213
    //http://blog.csdn.net/a351945755/article/details/23195713
    //http://blog.csdn.net/zhangzuomian/article/details/50324395
    //http://blog.csdn.net/henryzhang2009/article/details/38691415

    //
    //1,先打开网页,打开证书->详细信息->复制到文件->第2个选项 base64编码x.509(.cer) 导出为111.cer


    //2,使用java/bin 里面的工具

    参见:

    http://blog.csdn.net/a351945755/article/details/23195713

    里面的文章 .

     C:Userslinew>keytool -import -file E:111.cer -keystore e:mykeystore.jks

     这个证书是有密码的,一般都有密码.

     把 e:mykeystore.jks 改名成 mykeystore.keystore 

    这样java程序,就能识别这个文件流了,

    否则会报


    java.io.IOException: Invalid keystore format
    at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
    at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
    at java.security.KeyStore.load(Unknown Source)
    at SocketClient.Test1.getKeyStore(Test1.java:79)
    at SocketClient.Test1.getSSLContext(Test1.java:102)
    at SocketClient.Test1.initHttpsURLConnection(Test1.java:139)
    at SocketClient.Test1.main(Test1.java:231)
    2016-10-28 15:52:22 [MessageReceiver]-[ERROR] java.io.IOException: Invalid keystore format

    java写的client是用的

    http://blog.csdn.net/sunny243788557/article/details/38874153

    的.

    不过需要注意 . 

    MyHostnameVerifier.java里面的内容.
    不然 本地不安全的https程序,会报错.

    Test1.java的内容

    package SocketClient;
    
    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    import org.dom4j.Document;  
    import org.dom4j.DocumentException;  
    import org.dom4j.Element;  
    import org.dom4j.io.SAXReader;  
    
    import java.io.FileInputStream;
    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 java.io.BufferedReader;  
    import java.io.FileInputStream;  
    import java.io.IOException;  
    import java.io.InputStreamReader;  
    import java.net.MalformedURLException;  
    import java.net.URL;  
    import java.security.GeneralSecurityException;  
    import java.security.KeyStore;  
      
    import javax.net.ssl.HostnameVerifier;  
    import javax.net.ssl.HttpsURLConnection;  
    import javax.net.ssl.KeyManagerFactory;  
    import javax.net.ssl.SSLContext;  
    import javax.net.ssl.TrustManagerFactory;  
    
    
    import javax.net.ssl.HostnameVerifier;  
    import javax.net.ssl.SSLSession;  
    
    //import MyHostnameVerifier;
    
    
    
    
    
    public class Test1 {
    
        static Logger logger = null;
        
        
    
            /** 
             * 获得KeyStore. 
             * @param keyStorePath 
             *            密钥库路径 
             * @param password 
             *            密码 
             * @return 密钥库 
             * @throws Exception 
             */  
            public static KeyStore getKeyStore(String password, String keyStorePath)  
                    throws Exception {  
                // 实例化密钥库  
                KeyStore ks = KeyStore.getInstance("JKS");  
                // 获得密钥库文件流  
                FileInputStream is = new FileInputStream(keyStorePath);  
                // 加载密钥库  
                ks.load(is, password.toCharArray());  
                // 关闭密钥库文件流  
                is.close();  
                return ks;  
            }  
          
            /** 
             * 获得SSLSocketFactory. 
             * @param password 
             *            密码 
             * @param keyStorePath 
             *            密钥库路径 
             * @param trustStorePath 
             *            信任库路径 
             * @return SSLSocketFactory 
             * @throws Exception 
             */  
            public static SSLContext getSSLContext(String password,  
                    String keyStorePath, String trustStorePath) throws Exception {  
                // 实例化密钥库  
                KeyManagerFactory keyManagerFactory = KeyManagerFactory  
                        .getInstance(KeyManagerFactory.getDefaultAlgorithm());  
                // 获得密钥库  
                KeyStore keyStore = getKeyStore(password, keyStorePath);  
                // 初始化密钥工厂  
                keyManagerFactory.init(keyStore, password.toCharArray());  
          
                // 实例化信任库  
                TrustManagerFactory trustManagerFactory = TrustManagerFactory  
                        .getInstance(TrustManagerFactory.getDefaultAlgorithm());  
                // 获得信任库  
                KeyStore trustStore = getKeyStore(password, trustStorePath);  
                // 初始化信任库  
                trustManagerFactory.init(trustStore);  
                // 实例化SSL上下文  
                SSLContext ctx = SSLContext.getInstance("TLS");  
                // 初始化SSL上下文  
                ctx.init(keyManagerFactory.getKeyManagers(),  
                        trustManagerFactory.getTrustManagers(), null);  
                // 获得SSLSocketFactory  
                return ctx;  
            }  
          
            /** 
             * 初始化HttpsURLConnection. 
             * @param password 
             *            密码 
             * @param keyStorePath 
             *            密钥库路径 
             * @param trustStorePath 
             *            信任库路径 
             * @throws Exception 
             */  
            public static void initHttpsURLConnection(String password,  
                    String keyStorePath, String trustStorePath) throws Exception {  
                // 声明SSL上下文  
                SSLContext sslContext = null;  
                // 实例化主机名验证接口  
                HostnameVerifier hnv = new MyHostnameVerifier();  
                try {  
                    sslContext = getSSLContext(password, keyStorePath, trustStorePath);  
                } catch (GeneralSecurityException e) {  
                    e.printStackTrace();  
                }  
                if (sslContext != null) {  
                    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext  
                            .getSocketFactory());  
                }  
                HttpsURLConnection.setDefaultHostnameVerifier(hnv);  
            }  
          
            /** 
             * 发送请求. 
             * @param httpsUrl 
             *            请求的地址 
             * @param xmlStr 
             *            请求的数据 
             */  
            public static void post(String httpsUrl, String xmlStr) {  
                HttpsURLConnection urlCon = null;  
                try {  
                    urlCon = (HttpsURLConnection) (new URL(httpsUrl)).openConnection();  
                    urlCon.setDoInput(true);  
                    urlCon.setDoOutput(true);  
                    urlCon.setRequestMethod("POST");  
                    
                    
                    urlCon.setRequestProperty("Content-Length",  
                            String.valueOf(xmlStr.getBytes().length));  
                    urlCon.setUseCaches(false);  
                    //设置为gbk可以解决服务器接收时读取的数据中文乱码问题  
                    urlCon.getOutputStream().write(xmlStr.getBytes("gbk"));  
                    urlCon.getOutputStream().flush();  
                    urlCon.getOutputStream().close();  
                    
                    BufferedReader in = new BufferedReader(new InputStreamReader(  
                            urlCon.getInputStream()));  
                    String line;  
                    
                    System.out.println("收到信息:
    ");  
                    while ((line = in.readLine()) != null) {  
                        System.out.println(line);  
                    }  
                    
    
    
                   // urlCon.disconnect();
                    
                    
    //                urlCon.connect();
    //                DataOutputStream out = new DataOutputStream(urlCon.getOutputStream());
    //                out.write(xmlStr.getBytes("utf-8"));
    //                // 刷新、关闭
    //                out.flush();
    //                out.close();
    //                InputStream is = urlCon.getInputStream();
    //                if (is != null) {
    //                 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    //                 byte[] buffer = new byte[1024];
    //                 int len = 0;
    //                 while ((len = is.read(buffer)) != -1) {
    //                  outStream.write(buffer, 0, len);
    //                  //String sxxx(buffer,len);
    //                  System.out.println(outStream.toByteArray());  
    //                 }
    //                 is.close();
    //                 //return outStream.toByteArray();
    //                }
                    
                } catch (MalformedURLException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  

          

            if(urlCon!=null)
            {  
              urlCon.disconnect();
            }

    
            }  
        
        
        public static void main(String[] args) throws Exception
        {
            
            try 
            {
                
                logger=Logger.getLogger("MessageReceiver"); 
                
                PropertyConfigurator.configure(".\log4j.properties");
                
                
                int cccd=1;
                
    
                
                logger.error("信息:");
                
                ///
                //参考代码:
                //http://blog.csdn.net/sunny243788557/article/details/38874153
                //http://ln-ydc.iteye.com/blog/1335213
                //http://blog.csdn.net/a351945755/article/details/23195713
                //http://blog.csdn.net/zhangzuomian/article/details/50324395
                //http://blog.csdn.net/henryzhang2009/article/details/38691415
                
                //
                //1,先打开网页,打开证书->详细信息->复制到文件->第2个选项 base64编码x.509(.cer) 导出为111.cer
                //2,使用java/bin 里面的工具
                
                //
                ///
                
                // 密码  
                String password = "secret";  
                // 密钥库  
                String keyStorePath = "mykeystore.keystore";  
                // 信任库  
                String trustStorePath =  "mykeystore.keystore"; 
                // 本地起的https服务  
                String httpsUrl = "https://192.168.0.33:9443/index.html";  
                // 传输文本  
                String xmlStr = "JSON=true&key1112=这是测试&key=abc";  
                
    //            这是表单
    //            String xmlStr = "JSON=true&key1112=这是测试&key=abc";  
                
    //          这是这是xml
    //            String xmlStr = "<?xml version="1.0" encoding="UTF-8"?><fruitShop>sss</fruitShop>"; 
                
                initHttpsURLConnection(password, keyStorePath, trustStorePath);  
                // 发起请求  
                post(httpsUrl, xmlStr);  
                
    
            } 
            catch (Exception e) {
                e.printStackTrace();
                  logger.error(e.toString());
            }
            
            
    
        }
        
        
        
    }

    MyHostnameVerifier.java的内容

    package SocketClient;
    
    
    import javax.net.ssl.HostnameVerifier;  
    import javax.net.ssl.SSLSession;  
      
    /** 
     * 实现用于主机名验证的基接口。  
     * 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。 
     */  
    public class MyHostnameVerifier implements HostnameVerifier {  
        @Override  
        public boolean verify(String hostname, SSLSession session) {  
    //        
    //         原因:当访问HTTPS的网址。您可能已经安装了服务器证书到您的JRE的keystore 。但这个错误是指服务器的名称与证书实际域名不相等。
    //         这通常发生在你使用的是非标准网上签发的证书。 
    //
    //         解决方法:让JRE相信所有的证书和对系统的域名和证书域名。以下是一小段代码,可以用来实现
            
    //        这儿不验证 
            return true;
            
    //        if("localhost".equals(hostname)){  
    //            return true;  
    //        } else {  
    //            return false;  
    //        }  
        }  
    }  

    访问结果:

    2,python client 通过https访问 C++ 的https server

    不过这种方式 是没有带证书的方式去访问https.

    服务端是可能会拒绝的.

    服务端可以选择 是否必须要证书.

    #!/usr/bin/env python
    # coding:gbk #设置编码
    
    import sys
    
    import urllib2
    import urllib
    import  httplib
    import httplib2
    import cookielib
    import socks
    
    from HTMLParser import HTMLParser
    
    import win32com.client
    
    import PIL
    import Image
    import pytesser
    
    import ConfigParser
    
    import os
    import time
    import traceback
    import  shutil
    import uuid
    import wmi
    import zlib
    import pyDes
    import random
    import json
    import pypyodbc
    import ssl
    
    
    
    
    
    
    import urllib2
    import urllib
    from cookielib import CookieJar
    
    
    
    if __name__=="__main__":#入口函数
    
        import sys
        reload(sys)
        sys.setdefaultencoding('gbk')
    
        try:
    
            # opener = urllib2.build_opener(HTTPSClientAuthHandler('E:/any.pem', 'E:/any.pem') )
            # response = opener.open("https://192.168.0.33:9443/index.html")
            #
            # print response.read()
    
    
            # #读取配置文件
            config = ConfigParser.ConfigParser()
            config.read(sys.argv[0]+".ini")
    
            HttpsUrl=config.get("Set", "HttpsUrl")
    
            object_type=config.get("Set", "object_type")
            object_id=config.get("Set", "object_id")
            type=config.get("Set", "type")
            url=config.get("Set", "url")
            sys_name=config.get("Set", "sys_name")
    
            ssl._create_default_https_context = ssl._create_unverified_context
            cj = CookieJar()
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
            # input-type values from the html form
            strJson=('''
            {
            "object_type": "%s",
            "object_id": "%s",
            "notify": {
                "type": "%s",
                "url": "%s",
                "ext": {
                        "version": "V2C",
                        "user_name": "ocuser",
                        "user_password": "ocadmin1",
                        "auth_protocol": "SHA",
                        "content_encrypt_protocol": "DES",
                        "encrypt_password": "Huawei123",
                        "sys_name": "%s"
                        }
                    }
            }
            '''%(object_type,object_id ,type,url,  sys_name   ))
    
            formdata = { "data" : strJson}
            data_encoded = urllib.urlencode(formdata)#HttpsUrl
            response = opener.open(HttpsUrl, data_encoded)
            print response
            content = response.read()
    
            print "---------------
    "
    
            print content
            pass
    
        except Exception as ex:
    
            import traceback
            strInfo = traceback.format_exc()
            strInfo=("Exception:%s"%(strInfo))
            print strInfo
            CErrorLogOutput.funFormatOutput((strInfo),sys._getframe().f_code.co_filename,
                                                sys._getframe().f_lineno)
        finally:
            pass

    3,C++ 的https server 搭建.

    https 的搭建 先从openssl 的编译开始吧.

    openssl   这个之前一直打交道,一直在用,终于把他完整的编译了.

    http://www.cnblogs.com/bleachli/p/5775383.html

    poco-1.7.6-allNetSSL_OpenSSLdochowtobuild.txt 

    有说明

    "
    
    
    Windows
    =======
    
    The easiest way to install OpenSSL on Windows is to
    use a binary (prebuild) release, for example the
    one from Shining Light Productions that comes with
    a Windows installer.
    
    1. Download OpenSSL (at least v0.98a) from: 
    http://www.slproweb.com/products/Win32OpenSSL.html
    2. Install OpenSSL (we assume you install to c:OpenSSL)
    3. Start Visual Studio, go to Tools->Options, under Projects->VC++ Directories
    add the following directories:
    - Include Files: C:OpenSSLinclude
    - Library Files: C:OpenSSLlibVC
    4. You are now ready to build NetSSL.
    
    "
    
     

    之前用的 

    poco-1.6.0-all 这个版本,但这个版本的 Crypto 库与  Win32OpenSSL 有冲突.

    后面还是用的原生的

    openssl 的库,来解决这个问题.

    用了openssl  有lib,NetSSL_OpenSSL 才能正常编译.

  • 相关阅读:
    swiper 增加一个鼠标移入分页器的小点后就切换展示图片
    css中的单冒号和双冒号 以及 伪类和伪元素
    pointer-events: none;元素永远不会成为鼠标事件的target
    jQuery off() 方法
    jQuery方法汇总
    vue 数组修改 页面无法刷新
    mysql error Code 1441:datetime function: datetime field overflow
    生命的意义
    删除镜像或容器
    nginx Redis 不能访问问题
  • 原文地址:https://www.cnblogs.com/bleachli/p/6008154.html
Copyright © 2011-2022 走看看