socket如何提交表单到https?

弦苦 2009-09-17 11:25:27
<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 头部+参数"的格式吗?
请做过的大哥指导下,小弟不胜感激~~
...全文
410 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
弦苦 2009-09-20
  • 打赏
  • 举报
回复
我调用常规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握手、验证过程不是很熟悉。查了很多资料,像证书、验证这些都不太懂。
希望做过的兄弟指点一下,谢谢~~
弦苦 2009-09-18
  • 打赏
  • 举报
回复
在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怎么使用?
wshcdr 2009-09-18
  • 打赏
  • 举报
回复
关注
  • 打赏
  • 举报
回复
用openssl创建一个ssl连接在post数据过去即可跟非ssl的内容一致就对了。
西山小月 2009-09-17
  • 打赏
  • 举报
回复
用工具抓包先看一下提交表单的数据,然后用socket封装同样的数据传上去就行了。
抓http包的工具很多
arong1234 2009-09-17
  • 打赏
  • 举报
回复
这基本不可能,那一堆验证的报文你自己代价太高,估计你学几年都不一定做得出

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧