zoukankan      html  css  js  c++  java
  • Web Socket rfc6455 握手 (C++)

    std::string data((const char*)buf->data(),bytes_transferred);
    				recycle_buffer(buf);
    
    				std::string key="Sec-WebSocket-Key:";
    				auto pos = data.find(key);
    				auto posEnd = data.find("
    ",pos);
    				auto value = data.substr(pos + key.length(),posEnd - (pos + key.length()));
    				std::string sha1Src = trim(value);
    				sha1Src += std::string("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
    
    				unsigned char sha1out[20];
    				sha1((const unsigned char *)sha1Src.c_str(),sha1Src.length(),sha1out);
    				std::vector<unsigned char> data64;
    				for( auto c: sha1out) data64.push_back(c);
    
    
    				std::ostringstream os_rsp;
    				os_rsp<<"HTTP/1.1 101 Switching Protocols
    "
        				  <<"Upgrade: websocket
    "
    				      <<"Connection: Upgrade
    "
    				      <<"Sec-WebSocket-Accept: "<<base64Encode(data64)<<"=
    "
    					  <<"
    ";
    				std::string rsp = os_rsp.str();

    1) data 为连接建立以后,web socketclient发送的握手协议。

    2)查询到字段 Sec-WebSocket_key的值。而且拼接上GUID字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"值。

    得到 sha1Src

    3)对 key拼接后的值计算 sha1值,得到 sha1Out

    4)应答,最基本的就是计算 Sec-WebSocket-Accept值,通过函数 base64Encode进行计算;


    using namespace std;
    static const unsigned char bt[64]=
    {
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
    };
    std::string base64Encode(const std::vector<unsigned char> & data ){
    
    	std::list< std::bitset<8> > bits;
    	for( auto c : data ){
    	        std::bitset<8> bit(c);
    	        bits.push_back(bit);
    	}
    	while( bits.size() % 3 != 0 ) bits.push_back( bitset<8>() );
    
    	std::vector<unsigned char> base64;
    	while( !bits.empty() ){
    		std::bitset<6> bit6_1,bit6_2,bit6_3,bit6_4;
      		std::bitset<8> bit8_1 = *bits.begin(); bits.pop_front();
            std::bitset<8> bit8_2 = *bits.begin(); bits.pop_front();
            std::bitset<8> bit8_3 = *bits.begin(); bits.pop_front();
    
       		bit6_1.set(0, bit8_1[2]);
            bit6_1.set(1, bit8_1[3]);
            bit6_1.set(2, bit8_1[4]);
            bit6_1.set(3, bit8_1[5]);
            bit6_1.set(4, bit8_1[6]);
            bit6_1.set(5, bit8_1[7]);
    
            bit6_2.set(0, bit8_2[4]);
            bit6_2.set(1, bit8_2[5]);
            bit6_2.set(2, bit8_2[6]);
            bit6_2.set(3, bit8_2[7]);
            bit6_2.set(4, bit8_1[0]);
            bit6_2.set(5, bit8_1[1]);
    
            bit6_3.set(0, bit8_3[6]);
            bit6_3.set(1, bit8_3[7]);
            bit6_3.set(2, bit8_2[0]);
            bit6_3.set(3, bit8_2[1]);
            bit6_3.set(4, bit8_2[2]);
            bit6_3.set(5, bit8_2[3]);
    
            bit6_4.set(0, bit8_3[0]);
            bit6_4.set(1, bit8_3[1]);
            bit6_4.set(2, bit8_3[2]);
            bit6_4.set(3, bit8_3[3]);
            bit6_4.set(4, bit8_3[4]);
            bit6_4.set(5, bit8_3[5]);
    
        	base64.push_back( bt[bit6_1.to_ulong() ]);
            base64.push_back( bt[bit6_2.to_ulong() ]);
            base64.push_back( bt[bit6_3.to_ulong() ]);
            base64.push_back( bt[bit6_4.to_ulong() ]);
    	}
    	base64.pop_back();
    	string strdata(base64.begin(),base64.end());
    
    	return strdata;
    }

    5) 计算后把RSP发生出去就可以。



  • 相关阅读:
    从“窃听门”事件解读手机Rootkit攻击
    一款好用的开源信息安全管理系统演示(视频)
    P1908-逆序对
    P1010-幂次方
    P1226-快速幂
    P1433-吃奶酪
    ACM模板——玄学逐字符输入输出
    P1434-滑雪
    P1118-数字三角形
    P1443-马的遍历
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6761788.html
Copyright © 2011-2022 走看看