开发历程(5) WINCE 与 LINUX 通过SSL进行通讯

本文介绍了一种在WINCE5.0终端与LINUX服务器间通过SSL进行安全连接的方法。利用WININET库在WINCE端发起连接请求,而LINUX端则借助OPENSSL来响应并处理连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

终端采用WINCE5.0作为开发平台,服务器端采用LINUX,由于需要做到安全连接,用普通的SOCKET进行TCP无法达到安全级别,于是使用SSL进行连接通讯,经过测试,在WINCE端采用WININET库的函数,LINUX端采用OPENSSL。
在WINCE端主动发起连接,其流程是:
1.       用InternetOpen函数打开一个连接hOpen。
HINTERNET    hOpen = NULL;
hOpen = InternetOpen(L "MY SSL",
                        INTERNET_OPEN_TYPE_PRECONFIG,
                        NULL,
                        0,
       0);
 
2.       用InternetConnect,对打开的连接hOpen进行参数配置,设置IP,端口,连接方式,得到hConnect。
HINTERNET    hConnect = NULL;
hConnect = InternetConnect(hOpen,
                                L”192.168.0.1”,      //服务器 IP地址
                                L”5396”,             //服务器端口
                                NULL,
                                NULL,
                                INTERNET_SERVICE_HTTP,
                                0,
              0);
 
3.       用HttpOpenRequest开辟一个REQUEST内容句柄hReq,将需要传递的信息放 入该句柄内容。其中向服务器发送helloworld的消息。
HINTERNET    hReq = NULL;
hReq = HttpOpenRequest(hConnect,
                            L"GET",
                            L”helloworld”,
                            L"HTTP/1.0",
                            NULL,
                            (LPCTSTR*)AcceptTypes,
                            INTERNET_FLAG_SECURE|
INTERNET_FLAG_IGNORE_CERT_CN_INVALID|
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID,
                    0);
4.       用HttpSendRequest,向服务器发送REQUEST,并通过返回值,判断证书,最后连接上服务器,如果失败,可继续发送,如果超过3次,直接返回失败。
 
while(!HttpSendRequest(hReq, NULL, 0, 0, 0))
    {  
        printf("sendrequest error/n");
        dwError = GetLastError();
        if ( dwError == ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED)
        {
            printf("error_internet_client_auth_cert_needed/n");
            LPVOID dwCert = NULL;
            InternetErrorDlg( (HWND)GetDesktopWindow(),
                                hReq,
                                ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,
                                FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
                                FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
                                FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
                                &dwCert);
 
            InternetSetOption(hReq, INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT,
            dwCert, sizeof(dwCert));
            HttpSendRequest(hReq, NULL, 0, 0, 0);
            break;
 
        }else if(dwError == ERROR_INTERNET_INVALID_CA)
        {
            DWORD dwFlags;
            DWORD dwBuffLen = sizeof(dwFlags);
 
            InternetQueryOption (hReq, INTERNET_OPTION_SECURITY_FLAGS,
            (LPVOID)&dwFlags, &dwBuffLen);
 
            dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_CN_INVALID
                        | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
            InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS,
            &dwFlags, sizeof (dwFlags) );
            if(HttpSendRequest(hReq,NULL,0, 0, 0))
            {
                printf("sendrequest success/n");
            }else
            {
                printf("sendrequest error/n");
            }
            break;
        }
        n++;
        if(n == 3)
        {
            SSLerr = 1;
            //KillTimer(NULL,checktime);
            return 0;
        }
}   
 
5.       然后用阻塞方式等待服务器返回的数据,用InternetReadFile接受数据。
 
if(InternetReadFile(hReq,buf,100,&dwSize))
    {
        buf[dwSize] = '/0';
        printf("read success %s/n",buf);
    }else
    {
        printf("read error/n");
}
这时 buf收到的服务器发回的dwsize个字节的消息。
 
LINUX端的过程就是使用OPENSSL创建一个SSL服务器的过程,首先要在linux上安装好OPENSSL组件,否则无法调用SSL,然后要创建证书,当客户端发起连接时,发送给客户端提供身份认证,这些在这里都不详细叙述,都有详细的制作方法,创建服务器的过程也就是打开一个TCP连接,然后监听客户端发起的连接,并响应连接,由于为了说明SSL原理,对服务器程序并不重点介绍,这里使用开辟线程去处理连接,并在线程中进行SSL通讯。
1.       首先是前期的准备工作,
 
#define CERTF  "/opt/Mac/server.crt"
#define KEYF    "/opt/Mac/server.key"
SSL_METHOD  *meth;
X509          *client_cert;
OpenSSL_add_ssl_algorithms();        
        meth = SSLv23_server_method();     
ctx = SSL_CTX_new(meth);
然后加载证书
if(SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) == -1) 
        {
            printf("load the card error/n");
            exit(1);
        }else
        {
            printf("load the card success/n");
        }
 
        if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) == -1)
        {
            printf("load the privatekey error/n");
            exit(1);
        }else
        {
            printf("load the privatekey success/n");
        }
 
          if (!SSL_CTX_check_private_key(ctx))
        {
            printf("Private key does not match the certificate public key/n");
            exit(1);
        }else
        {
            printf("Private key match the certificate public key success/n");
}
2.       用TCP连接方式建立一个服务器程序然后建立循环等待连接,这里核心代码是
while(1)
        {
     temp_sock_descriptor = accept(Sock_Descriptor,(struct sockaddr*)&sin,&len);
      pthread_create(&id,NULL,(void*)thread,&temp_sock_descriptor);
}
这里当连接到来时,立刻开辟一个线程thread去处理,然后进入线程。
              进行SSL处理:
              SSL      *ssl = SSL_new(ctx);                                                    SSL_set_fd(ssl,temp_sock_descriptor);
        SSL_set_accept_state(ssl);
        SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
        SSL_accept(ssl);    相当于接受客户端的 SSL连接
        Num = sizeof(buf);
        SSL_read(ssl, buf, num);    读取客户端发送的信息到 buf
        Printf(“%s”,buf);查看收到的信息,其中包括客户端的所有信息。
        Memset(buf,’/0’,num);
        Strcpy(buf,”hello”);
        Num = strlen(buf);
        SSL_write(ssl,buf,num);     向客户端发送消息
        SSL_free(ssl); 
        close(temp_sock_descriptor);
        这样整个 SSL通讯的基本过程就是这样,可以在这个基础上使用SSL发送需要保密的信息。
可以使用普通的浏览器访问刚刚建立的 SSL服务器,如果服务器IP是
192.168.0.1,绑定的端口是 5396;
那么,在浏览器地址输入栏输入
        按确定后,会弹出警告框,因为证书不是浏览器默认的安全证书,这时继续操作,     就会看到窗口显示hello。
如果用 wince访问服务器,打印收到的字符串,显示也是hello,这样SSL通讯基本实现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值