<form name='staticlogin' method='POST' action='https://221.176.1.140:443/do_login.php'>
<input type='hidden' name='USER' value='fantasy'>
<input type='hidden' name='PWD' value='9999'>
</form>对于HTTP表单,直接利用socket进行TCP80的HTTP POST没问题。
对于这种action指向HTTPs的表单如何用socket提交USER和PWD参数呢?
我用嗅探器看了下,Server: Apache/2.0.58 (Unix) PHP/5.2.1 mod_ssl/2.0.58 OpenSSL/0.9.7i
TCP443发送过去的参数与填写的不一样,这个应该客户端的数据POST之前有个SSL加密?
大概是socket+OpenSSL。请问这个要怎么处理?
与221.176.1.140建立TCP443连接后,怎样发送数据?
也是按HTTP POST的格式"POST /do_login.php 头部+参数"的格式吗?
请做过的大哥指导下,小弟不胜感激~~

解决方案 »

  1.   

    用工具抓包先看一下提交表单的数据,然后用socket封装同样的数据传上去就行了。
    抓http包的工具很多
      

  2.   

    在WinInet API中:
    HttpOpenRequest opens an HTTP request handle. HINTERNET WINAPI HttpOpenRequest(
    HINTERNET hConnect, 
    LPCTSTR lpszVerb,  
    LPCTSTR lpszObjectName, 
    LPCTSTR lpszVersion, 
    LPCTSTR lpszReferrer, 
    LPCTSTR *lplpszAcceptTypes, 
    DWORD dwFlags, 
    DWORD dwContext );
    Uses SSL/PCT transaction semantics.  
    dwFlags = INTERNET_FLAG_SECURE,则表示使用SSL/PCT传输机制。确实能对HTTPs进行正确的Get和Post。
    我现在主要是多网卡的情况,所以要绑定IP,WinInet貌似没有bind功能。所以,我就用socket。查了资料,基本就是socket + OpenSSL的方案,建立一个SSL_socket.
    我下载了OpenSSL 0.9.8K,然后编写以下代码:
    //创建套接字
    SOCKET s=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s==INVALID_SOCKET)
    {
    printf("Failed socket() \n");
    ::WSACleanup();//DLL卸载
    return 0;
    }

    // char * ch = "127.0.0.1";  // HTTPs服务器IP地址
    struct sockaddr_in servAddr; 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = htons(443);
    servAddr.sin_addr.s_addr = inet_addr("221.176.1.140");

    if (connect(s,(struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) 

    printf("connect faild"); 
    return 1; 

            ……………………………………………………………………………………………………
    SSL_load_error_strings(); 
    ERR_load_BIO_strings(); 
    OpenSSL_add_all_algorithms(); 
    ////////////////////////////////////////////////////////   
    SSL_CTX * ctx = NULL; 
    ctx = SSL_CTX_new(SSLv2_client_method()); //申请的 SSL通讯方式 服务版本2/3 
    if (ctx == NULL) 

    // ERR_print_errors_fp(stdout); 
    printf("create faild\n"); 
    }
    SSL * pSSL = NULL; 
    pSSL = SSL_new(ctx); //创建一个新SSL
    BIO * sbio = BIO_new_socket(s,BIO_NOCLOSE); 
    if (sbio == NULL) 

    printf("sbio error \n"); 

    SSL_set_bio(pSSL,sbio,sbio); 
    SSL_set_fd(pSSL, s);   //该函数将Socket描述符fd设置为BIO的底层IO结构,同时可以设置关闭标志 
    if (SSL_connect(pSSL) == -1) //创建一个SSL连接 

    printf("ssl_connet error \n"); 
    }
                    // sendmess为HTTP POST头部
    int nrect = SSL_write(pSSL, sendmess, strlen(sendmess)); 
    while(nrect > 0) 

    nrect = SSL_write(pSSL,sendmess+nrect,strlen(sendmess)-nrect); 

    if (nrect == 0) 
    break; 

    memset(sendmess,0,2024); 
    char tmpnum[512]; 
    while (recvnum > 0) 

    memset(tmpnum,0,512); 
    recvnum = SSL_read(pSSL,recvmess,512); 
    if (!recvmess) 

    strcpy(recvmess,tmpnum); 

    else 

    strcat(recvmess,tmpnum); 

    printf(tmpnum); 

    printf("-%d-%d--%s\r\n",recvnum,strlen(recvmess),recvmess); 
    SSL_CTX_free(ctx); 
    closesocket(s);
    这个编译0 error(s), 0 warning(s)。运行后connect(s,(struct sockaddr*)&servAddr, sizeof(servAddr))连接成功。但是ctx = SSL_CTX_new(SSLv2_client_method()); 这一句就出错了。
    我想问一下,这么做(socket + SSL)对不?
    然后SSL怎么使用?
      

  3.   

    用openssl创建一个ssl连接在post数据过去即可跟非ssl的内容一致就对了。
      

  4.   

    我调用常规socket::connect到221.176.1.140:443后,使用OpenSSL建立了SSL_connect。然后调用SSL_write将构造的HTTP POST数据包发送到 /do_login.php。调用SSL_read,确实得到服务器的回应:
    ==============================
    HTTP/1.1 200 OK
    Date: Sun, 20 Sep 2009 12:09:19 GMT
    Server: Apache/2.0.58 (Unix) PHP/5.2.1 mod_ssl/2.0.58 OpenSSL/0.9.7i
    X-Powered-By: PHP/5.2.1
    Set-Cookie: PHPSESSID=42tmdnuugkh8mibtdqu828dnj3; path=/
    Content-Length: 117
    Connection: close
    Content-Type: text/html; charset=gbk
    <html><body><script language="JavaScript">
    alert("登录认证失败,请联系10086!");
    history.back();
    </script>
    </html>
    </body>
    烫烫烫
    ==============================
    但我用WinInet发送同样的参数,POST过去验证成功。
     
    主要是我对SSL握手、验证过程不是很熟悉。查了很多资料,像证书、验证这些都不太懂。
    希望做过的兄弟指点一下,谢谢~~