2

I have a windows application which listens on 9002 port via system.net.socket.

If clients send the request over http url like that:

http://localhost:9002/projectName/doSomething

then in my ReceiveCallBack method the received data is:

POST /projectName/doSomething HTTP/ 1.1
Accept: * / *
Origin: http://localhost
Accept-Language: tr-TR
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko
Host: localhost:9002

But if they send the request over https url which you can see below:

https://localhost:9002/projectName/doSomething

then the received data is something like:

\0?\0\0?U:vv?W?????????T??k#?=??? v\tci\0\0,?(?'??\0=\0<\05\

I tried to use UTF8 encoding to convert this data in a readable format and searched over the Internet but I could not find the solution.

What is the way of receiving a readable data over HTTPS requests?

Thanks

Orkun Bekar
  • 1,447
  • 1
  • 15
  • 36
  • 1
    Why are you sending HTTP requests over sockets? – usr Apr 24 '15 at 17:15
  • @usr I don't send HTTP requests. My socket listens on a port. The client send HTTP request over internet browser. I catch the request and do something according to the request. – Orkun Bekar Apr 24 '15 at 18:12
  • OK, why are you receiving HTTP requests using a socket, then? Can't you use one of the standard HTTP listener libraries? – usr Apr 24 '15 at 18:14
  • HttpListener does not allow listening ports if you are not administrator. I searched this kind of listeners a lot and I decided that socket is the best. – Orkun Bekar Apr 24 '15 at 18:17
  • OK. I advise you to not parse HTTP requests manually. This is a lot more work than you might think. Anyway, the question is valid. – usr Apr 24 '15 at 18:27
  • Actually I have a good working application. The client was using http and there was no problem till now. Now they changed their system to https, so I have to change my socket listener too. – Orkun Bekar Apr 24 '15 at 18:30
  • I find something about sslstream sockets etc. on the net but most of them uses TCP listener. I really have to use socket. No other way. Also not enough time :) – Orkun Bekar Apr 24 '15 at 18:32

2 Answers2

1

You are probably seeing the first round of the handshake protocol for https. In https the two computers go through a multi-step handshake to negotiate what encryption to use, exchange public keys, etc. Even if you get through the handshake phase the data will be encrypted (which is kinda the point of using https).

Kevin
  • 1,462
  • 9
  • 9
  • But I'm waiting until all data received and the final data is formed by unrecognized characters as I show in my question. – Orkun Bekar Apr 24 '15 at 18:43
  • That doesn't change the fact that the data is encrypted. The purpose of https is to prevent "bad guys" from intercepting data in route then passing it along to the intended recipient (man in the middle attack). Since you are using "raw" socket code, none of the handshake/key exchange/decryption is being performed for you, you would have to code it for yourself. Which would not be a trivial exercise. – Kevin Apr 24 '15 at 18:55
  • I'm still searching but I could not find a way. How can I code it myself? Could you make it more clear? – Orkun Bekar Apr 24 '15 at 19:49
  • Think of it like this, since you are writing a piece to process requests from a browser, you are essentially writing a custom web server (think IIS, Apache). Http was easy, the browser sends you everything in plain text and you respond in plain text - easy peasy. Now that you want to support a more complex protocol (ssl/tls over tcp - https) you have to implement the server side of the secure conversation just like IIS and Apache does. I'd suggest you look at the code for OpenSSL to see how it is done. – Kevin Apr 24 '15 at 19:53
  • Now that I think about it, you'd probably be better off looking in the code for Apache web server to see how it is done. I think it is written in C++, but it is open source and maybe it would set you on the right path. – Kevin Apr 24 '15 at 20:06
  • Also give RFC 2246, RFC 2818, RFC 5246, RFC 6101 a look. As well as this TechNet link about how SSL/TLS works https://technet.microsoft.com/en-us/library/cc783349(v=ws.10).aspx – Kevin Apr 24 '15 at 20:14
1

I've actually written a web server and SOAP stack in C# from sockets up without using any WCF or HttpListener and had to deal with adding https support. The code was actually relatively simple.

You'll need to start by constructing a SslStream from the Socket, by way of a NetworkStream adapter.

var sslStream = new SslStream(new NetworkStream(socket));

Then the hard part: you need to AuthenticateAsServer, which requires you to have an X509Certificate with corresponding private key, from an issuer the connecting client trusts, containing a subject name matching the host portion of the https URL. (It's the hard part because you can't code your way out of it unless you own both sides of the connection - it's how a client such as a browser knows if a site is legitimate or not.)

sslStream.AuthenticateAsServer(serverCertificate);

Finally, you can then read from the sslStream and get the actual, unencrypted HTTP request.

Jeffrey Hantin
  • 35,734
  • 7
  • 75
  • 94
  • Thanks. I'm waiting for the client feedback about certification file. Also I'm looking at the samples but I could not find so many examples with socket. For http requests my multithreaded async socket is working good. I hope I also add https support without changing the general shape. – Orkun Bekar Apr 25 '15 at 12:41
  • @Orkun, the one likely major change will be that your HTTP code will need to use a `Stream` instead of direct `Socket` access. `NetworkStream` alone adapts a TCP connection (or other streaming-mode socket) as a `Stream`, and is what I use for non-SSL connections. – Jeffrey Hantin Apr 26 '15 at 22:18
  • I'm not so familiar with web part but it uses XDomainRequest for sending and receiving data. Do I have to change something there or do you mean I will have to change async socket structure to something else on my C# side? – Orkun Bekar Apr 26 '15 at 22:30
  • The socket structure on the C# side will have to become a stream structure. Both types support asynchrony but the methods change. – Jeffrey Hantin Apr 27 '15 at 00:19
  • I request you to look at my new [question](http://stackoverflow.com/questions/29875726/how-to-create-sslstream-for-a-non-blocking-async-socket). It is probably caused by just lack of private key. I will get it from customer but maybe you write something about the new structure or give me a link etc. Thanks. – Orkun Bekar Apr 27 '15 at 07:10