Best way to download files if username and password correct

Associate
Joined
16 Aug 2010
Posts
1,373
Location
UK
I'm writing a program (was C#, but doing C++ now) for someone, where a user enters username and password and then if correct, it should download some files.

The username and passwords are the username and passwords from a mysql database (ip boards in fact).

I was wondering what is the most secure way to do this in terms of not anyone being able to download the files. For example, I don't really want it in the program if the server responds username and password correct, it then uses a username/password to download from an ftp server, incase someone tries to get this from the program. I want the "path" to be through the program, not bypassed.

Essentially I want some sort of program that sits on the server, receives a request from a client, checks if they are in the DB, if they are, send the files over. I'd rather not write my own if possible, to save time. Maybe a program isn't needed, maybe there is an easier way. Not sure, why I am asking here. It seems like a common thing to do, although Google isn't returning much (maybe I am being rubbish!). Hope this makes sense. Thanks :p
 
Last edited:
Associate
Joined
5 Jun 2015
Posts
11
Location
Somewhere along the M5 :)
You’ll probably want something like follows:
Local app asks for username/password
Sent to PHP/ASP script on web server as querystring. ** use https to stop MITM attacks **
Server side script connects to mysql database, does lookup of correct password.
Run user entered password through hashing algorithm (probably this: md5(md5($salt).md5($password)) http://stackoverflow.com/questions/27993890/ipboard-password-hashing-issue-doesn't-match-algorithm, compare with one in database.
If correct, server script opens requested file and passes back to local app as filestream, otherwise returns http 403 code.
Local app checks status code of response, if not 403, saves temporary file.

If you do it this way, the actual location of the file is never revealed to the local app. Downside is if your files are large then the server scripting language does lots of work to read and then pipe.

You may also want to encrypt your querystring using a common phrase + salt just to make it harder to reverse engineer what’s happening.

I’ve done something similar in ASP.net (C#), although it wasn’t a Win32 app doing the downloading.
Matt
 
Associate
OP
Joined
16 Aug 2010
Posts
1,373
Location
UK
The size of the files will be a few GB possibly, especially if a user is downloading a first time. In the future only necessary files will be updated.

I was going to send the password from client to server already hashed, since I thought sending raw passwords over the net is obviously bad practice?

The client program was originally going to be C#, but I was concerned could be too easy to reserve engineer. Sure you can do it to C++ as well, but it's harder I believe.
 
Associate
Joined
5 Jun 2015
Posts
11
Location
Somewhere along the M5 :)
You won’t be able to salt the password on the client unless you get the salt from the database first.

If you get a certificate for the server, you can do HTTPS which will let you pass password ‘in the clear’ with minimal risk (as long as the certificate if the one you’re expecting – have a look at certificate pinning as a technique).

To be honest, decompiling the program would be the hardest way of reverse engineering this – easiest thing to do would be to watch network traffic using wireshark or similar.
 
Associate
Joined
5 Jun 2015
Posts
11
Location
Somewhere along the M5 :)
You'll get people in both camps.. I've had a lot more experience in c#, so I would go with that. .net languages tend to be slightly easier to work with and do memory management and whatnot automatically.

Other things to take into account.. Is this going to be cross platform? You mentioned QT..
.net has mono for Linux that is good enough for games to run on (thinking Cities: skylines here).

What is the purpose of the app - if it's just to download files, would a compiled script work better? Or even just a web page with login?
 
Associate
OP
Joined
16 Aug 2010
Posts
1,373
Location
UK
Nope, just Windows. Used a lot of QT though, I also know C#.

It's a launcher for a mod of a game. People are granted access to it by being put into a certain usergroup on the forums - as I said ipboards. Don't want any old Tom managing to download the files.

Launcher also has options for the startup of the game, website, teamspeak, news feed from RSS/xml.
 
Associate
Joined
21 May 2013
Posts
1,991
The language of your implementation shouldn't matter so long as your implementation is reasonably secure. If you're concerned that somebody decompiling the app could get unauthorized access to files, then you're trusting the client with too much information and your implementation is wrong.

PHP 5.5 has password hashing functions that use a cryptographically secure pseudo-random number generator; you should ideally use these if they're available to you.

See: http://php.net/manual/en/function.password-hash.php
and http://php.net/manual/en/function.password-verify.php

If you're interested in the theory behind secure password hashing, this is a pretty good read: https://crackstation.net/hashing-security.htm

If you're concerned about potential sniffing of local network traffic an SSL certificate to verify the server is the right way to go about it as mentioned before. No solution will be entirely foolproof; all you can do is use the best tools you have access to at the time. For example, what's to stop an authorized user from transferring the files elsewhere after they've downloaded them?
 
Last edited:
Associate
Joined
21 May 2013
Posts
1,991
What's the proposed structure of your system? Are your database server, file server and web server all on the same machine?
 
Associate
OP
Joined
16 Aug 2010
Posts
1,373
Location
UK
The IP boards and webserver are on the same system, there will be multiple servers hosting the files, US and EU.

Yeah I agree they could pass them around, but still, it's a slight improvement if not just anyone can connect and download.
 
Soldato
Joined
18 Oct 2002
Posts
7,492
Location
Maidenhead
Is the game loader yours? If so, you could build the login in to that, so anyone can download it, but only legitimate users can do anything with it?
 
Associate
OP
Joined
16 Aug 2010
Posts
1,373
Location
UK
I've got everything set up and sending the files through php if authenticated etc. I am sending the data via chunks (best way apparently) from the php.

Code:
while (!feof($handle) && (connection_status() === CONNECTION_NORMAL))  
{ 
        $buffer = fread($handle, $chunksize); 
	print $buffer; 
	ob_flush(); 
	flush(); 
}

Chunksize is 8 MB.

The C# is (with 1mb buffersize)

Code:
byte[] downBuffer = new byte[iBufferSize];

while ((iByteSize = smRespStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
                saveFileStream.Write(downBuffer, 0, iByteSize);
}

 saveFileStream.Close();
smRespStream.Close();

Files under 8MB are fine. Ones over however are not, as their md5 checksum is different. The total sum of iByteSize per iteration seems to add up to the file size (obtained from the header with ContentLength on the httpwebresponse). I've been googling and reading, but still not solved the problem. Comparing the binary of two files just over 8mb (10mb), even though they both say the same size, the downloaded one is shorter in terms of the number of lines of (mostly) gobbledygook. Does anyone have any suggestions?
 
Last edited:
Back
Top Bottom