Jump to content
xisto Community

zakaluka

Members
  • Content Count

    130
  • Joined

  • Last visited

Everything posted by zakaluka

  1. Most basic routers do not provide support traffic shaping. I'm not sure which one yours is, but one solution is to get your hands on a really cheap, old PC (almost any PC from the last 10 years will do) and 2 network cards. Install IPCop or BrazilFW on it. Then, you can implement quality of service traffic shaping so that all traffic from your PC has higher priority than hers.The network setup would look like this: ISP ----- Zyxel router ----- PC w/IPCop ----- Your PC | | | Sister's PC While this solution is not free, it will give you a lot of power. Plus, you may be able to get a cheap PC for free if a friend / relative is throwing out their old computer.Regards,z.
  2. It all comes down to 1 thing - if something goes wrong, how bad will you feel that you now have a $200+ brick? Also, how technically proficient are you to be able to debug problems and fix things yourself when it doesn't go according to plan? Several jailbreak techniques let you restore the original firmware. So, you could conceivably do that and update your iPod / take it in for servicing, then restore the custom firmware you've made to continue using apps not approved by Apple. An issue to consider - Is jailbreaking illegal? https://www.eff.org/deeplinks/2009/02/applereaking-illegal . There has been no decision yet (as far as I know), but we will just wait and see. Regards, z.
  3. This is a tutorial for how to authenticate users when you have an online service without SSL support. Basic scenario You have an online service that requires people to register and log in to use correctly. However, due to any number of issues, you do not have SSL support available for the service. How do you protect your users' passwords when they are registering / logging in AND make it so that it is harder for someone to impersonate them? I will give an overview, followed by code (or pseudo-code) and explanations, as appropriate. Prerequisite knowledge You should know what PHP and Javascript are. You should have an understanding of what hashing is, particularly cryptographic hashes such as MD5, SHA-1, and so on. Certain hashes, including cryptographic hashes, are "one-way", i.e. there is no feasible mathematical way to un-hash a string in order to retrieve the original data. Regardless, there are things attackers can try to find your original text. In contrast, encryted text can be decrypted, given the same key. Potential attacks Before discussing techniques, it makes sense to see what kinds of attacks are possible on your services and how they work. This will help understand why certain techniques are better than others. Dictionary attacks In this attack, the attacker sits down with a huge list of words and tries them all against a hash function until he finds a match. This attack is a more refined version of a general brute force attacks. In a brute force attack, the attacker will systematically try every character combination within a given key space (combination of usable characters * (1 .. maximum length)). In this case, the attacker will use the most common words that have a chance of succeeding. In the majority of cases, these words come from English dictionaries. The reason this attack is successful is that people tend to choose passwords that are short (<= 7 characters) words from the dictionary simple variations on dictionary words (appending a digit, misspelling by one letter, etc.) Rainbow tablesRainbow tables are lists of plaintext passwords and their hashes. In essence, the attacker is precomputing hashes for a large selection of potential passwords. In order to crack your user's password, they will simply compare the hash against the ones in their table. If they find a match, the corresponding plaintext password is made available to the attacker. Please note that this is NOT decryption or dehashing (despite names like MD5 Decrypter). It is simply a huge lookup table. By creating such a table, an attacker is trading off time for memory. These attacks are preferred when going against multiple sites, since the hashes only have to be calculated once. Brute force This is the most time-consuming attack of the ones presented here. The attacker writes an algorithm which checks every character combination within a given key space in the hopes of finding a match. Even with regular English words, this attack takes a long time and a lot of computing power. Making a long password and adding symbols, digits and other special characters makes this attack essentially impossible to implement in practice. Assumptions we can safely make Given what we know about the above 3 attacks, there are some basic assumptions we can make on the kind of security we want to implement. We want to encourage users to not use simple passwords by enforcing good password selection in the code. In addition, we don't want to use encryption to protect passwords. The reason is simple: as stated above, anything that has been encrypted can be decrypted. The attacker just needs to get a hold of the key to get a hold of the plaintext password. So, we definitely want to use hashes whenever dealing with passwords. NOTE: The logic used in the following 2 sections (Registration and Authentication) is not representative of how you would do it in the real world. For that, go to the section called Bringing it all together. Registration The very first problem we have to deal with is registration. Basically, we want to ensure that the user's password is protected at all times. Obviously, transmitting the username / password in the clear to the back-end is out of the question. Any attacker who is watching a site / packet sniffing along the path can get a hold of the information without having to do almost any work. The second option is to hash the password before sending it to the server. This avoids the problem of revealing the password to attackers. As was revealed recently (Do you use the same password for every website?), a large percentage of internet users like to reuse their passwords on each site. This means that, on average, you are keeping 1/3 of your users safe from attacks at other online services. This is done easily in PHP using code similar to: $hashpw = hash('sha256', $pw);The third option is to "salt" the password before hashing it. While this suffers from the same problem as the previous option, it defeats the Rainbow table attack. This is especially true since each user will (or, at least, should) have their own unique salt. So, what is salting? Salting is basically taking an additional string and appending it to the password before hashing it. For example: $hashed_password = hash('sha256',$password.'this is a salt');But, as I just mentioned, the salt should be unique for each user. Otherwise, there is no purpose to adding the salt. Here is code to create a salt that is somewhat more secure: // $salt = hash('sha256', uniqid(mt_rand().$_SERVER['REMOTE_ADDR'].$_SERVER['REQUEST_TIME'], true)); // you get the idea $hashpw = hash('sha256', $pw.$salt); linenums:0'>$salt = hash('sha256', uniqid(mt_rand(), true));// $salt = hash('sha256', uniqid(mt_rand().$_SERVER['REMOTE_ADDR'].$_SERVER['REQUEST_TIME'], true)); // you get the idea$hashpw = hash('sha256', $pw.$salt); The salt must be stored in the database along with the hashed password so that the password can be authenticated every time. In addition to salting a password, we will introduce one more wrench to confound attackers. This is the "pepper." The concept of a pepper is identical to that of a salt. However, instead of storing it on the database, we store it in a regular file on the server. Why is this? It's to simply make it harder for someone to get into your systems. Let's say an attacker is able to get access to your database. Without also getting access to your server's file system, they will be unable to get a hold of the pepper. So, how do we use this? Here's a small code sample: $salt = calc_salt(); // such as with the hash() above$pepper = read_pepper_from_disk();$hashpw = hash('sha256', $pw.$salt.$pepper);It's that simple. The way a salt differs from a pepper is that the pepper is the same for all users. This is because if the pepper is unique for all users, you have to maintain separate pepper files for each user, defeating the purpose of having a database in the background. We also keep the salt static to avoid having to recalc potentially tens of thousands of passwords for each change. Plus, if an attacker is able to get your pepper, it probably means she has access to your file system and you are in deep trouble anyway. For now, without extensions, this is about the best PHP can do without using more complicated encryption methods like public/private key pairs. PHP 5.3 will include OpenSSL functions, which include a much better random number generator for additional security. Authentication The next challenge we face is authentication, i.e. logging an user in safely when they revisit your site. Authentication works exactly like registration, but with less calculations. Here is the basic concept: if ($hashpw == read_user_hashedpw_from_DB()) { return 'AUTHENTICATED'; } else { return 'REJECTED'; } linenums:0'>$salt = read_user_salt_from_DB();$pepper = read_pepper_from_disk();$hashpw = hash('sha256', $pw.$salt.$pepper);if ($hashpw == read_user_hashedpw_from_DB()) { return 'AUTHENTICATED';} else { return 'REJECTED';} Since the various functions above will be different for each site, implementation is left to the reader. In addition to doing all this, here is an advanced technique you can use to really stump attackers. It is called dynamic salting. The theory behind it sounds complex, but it is quite simple and will force attackers to restart their attacks each time the user logs in. The idea is to change the salt each time a user logs in. While this technique works best if an user logs in often, the process does not become less safe just because we use it for an user who only logs in infrequently. Here is the concept (in pseudo-code): update_user_salt_in_DB($userid, $new_salt); update_user_hashedpw_in_DB($userid, $new_hashpw); } linenums:0'>if ($login_is_successful) { $new_salt = calc_salt(); // using the same function as for registration. $new_hashpw = hash('sha256', $pw.$new_salt.$pepper); update_user_salt_in_DB($userid, $new_salt); update_user_hashedpw_in_DB($userid, $new_hashpw);} Bringing it all togetherIf you've hung around so far, here is the part where I talk about how to implement this technique step-by-step. There are steps not addressed above, which will be dealt with here (such as how to get the password from the browser to the server without it being visible to everyone). I am showing the steps for getting authentication working. The steps for registration are almost identical. Step 1 - In the browser On the web page, have 2 forms: 1 visible form with fields for the username and password, one with no visible fields that can be used to submit the information to a PHP script. Put all this into a file called login.php. Some PHP in support of dynamic salting: ?> linenums:0'><?php$new_salt = hash('sha256', uniqid(mt_rand(), true));?> Form 1 (HTML): <form id="loginVisible" action="#" method="post"><input type="text" name="username" /><input type="password" name="password" /><input type="button" name="submit" value="Login" onclick="login();" /></form>Form 2 (HTML): <form id="submitAuthenticate" action="authenticate.php" method="post"><input type="hidden" name="username" /><input type="hidden" name="securepw" /><input type="hidden" name="salt" /><input type="hidden" name="newsaltpass" /></form>JS login() script: <!-- public domain SHA-256 JS implementation --><script type="text/javascript" src="benjaminjohnston.com.au/sha256.js; /><script type="text/javascript">var login_form;var xml_http;var url;var current_salt;var current_hashpass;function login() { login_form = document.getElementById("loginVisible"); xml_http = new XMLHttpRequest(); url = "get_salt.php?u=" + login_form.username.value; url = url + "&sid=" + Math.random(); xml_http.onreadystatechange = state_change; xml_http.open("GET", url, false); xml_http.send(null);}function state_change() { if (xml_http.readyState != 4) { alert("Something went wrong with XMLHTTPRequest!"); return false; } current_salt = xml_http.responseText; current_hashpass = sha256.process(login_form.password.value + current_salt); var submit_authenticate = document.getElementById("submitAuthenticate"); submit_authenticate.username.value = login_form.username.value; submit_authenticate.securepw.value = current_hashpass; submit_authenticate.salt.value = <?php echo $new_salt ?>; submit_authenticate.newsaltpass.value = sha256.process(login_form.password.value + submit_authenticate.salt.value); submit_authenticate.submit();}</script> On the back-endpepper.php: $pepper = "0123456789ABCDEF";get_salt.php: include 'mysql_init.php'; // You need to initialize the connection to mysql, this is left as an exercise to the reader // mysql_init(); // Initialize the DB connection here, connect to correct DB, and so on. $query_result = mysql_query("SELECT users.salt FROM users WHERE users.username = " . $_REQUEST["u"]); $result_array = mysql_fetch_array($query_result, MYSQL_NUM); echo $result_array[0]; mysql_free_result($query_result); // clean up mysql connection here ?> linenums:0'><?phpinclude 'mysql_info.php'; // You should have your Mysql IP, Port, Username, Pass in this.include 'mysql_init.php'; // You need to initialize the connection to mysql, this is left as an exercise to the reader// mysql_init(); // Initialize the DB connection here, connect to correct DB, and so on.$query_result = mysql_query("SELECT users.salt FROM users WHERE users.username = " . $_REQUEST["u"]);$result_array = mysql_fetch_array($query_result, MYSQL_NUM);echo $result_array[0];mysql_free_result($query_result);// clean up mysql connection here?> authenticate.php: include 'mysql_init.php'; // You need to initialize the connection to mysql, this is left as an exercise to the reader // mysql_init(); // Initialize the DB connection here, connect to correct DB, and so on. include 'pepper.php'; $entered_password = hash('sha256', $_REQUEST["securepw"].$pepper); $query_result = mysql_query("SELECT users.password FROM users WHERE users.username = " . $_REQUEST["username"]); $result_array = mysql_fetch_array($query_result, MYSQL_NUM); $db_password = hash('sha256', $result_array[0] . $pepper); mysql_free_result($query_result); // Dynamic salting at work. if ($entered_password == $db_password) { $new_salt = $_REQUEST["salt"]; $new_salt_pass = $_REQUEST["newsaltpass"]; mysql_query("UPDATE users SET users.salt=" . $new_salt . ", users.password=" . $new_salt_pass . " WHERE users.username = " . $_REQUEST["username"]); // clean up myql connection here. } else { header("Location linenums:0'><?phpinclude 'mysql_info.php'; // You should have your Mysql IP, Port, Username, Pass, etc. in this.include 'mysql_init.php'; // You need to initialize the connection to mysql, this is left as an exercise to the reader// mysql_init(); // Initialize the DB connection here, connect to correct DB, and so on.include 'pepper.php';$entered_password = hash('sha256', $_REQUEST["securepw"].$pepper);$query_result = mysql_query("SELECT users.password FROM users WHERE users.username = " . $_REQUEST["username"]);$result_array = mysql_fetch_array($query_result, MYSQL_NUM);$db_password = hash('sha256', $result_array[0] . $pepper);mysql_free_result($query_result);// Dynamic salting at work.if ($entered_password == $db_password) { $new_salt = $_REQUEST["salt"]; $new_salt_pass = $_REQUEST["newsaltpass"]; mysql_query("UPDATE users SET users.salt=" . $new_salt . ", users.password=" . $new_salt_pass . " WHERE users.username = " . $_REQUEST["username"]); // clean up myql connection here.} else { header("Location:login.php?error=".urlencode("Failed authentication")); exit;}?> Pros The user's password is safe. It is never transmitted in the clear over the network. You are doing quite a lot to discourage attackers from getting into your site. The new salt generation can also be used for generating strong Session IDs for PHP sessions (a topic I didn't cover here). Cons All communication is occurring in the open, i.e. anyone sniffing packets will be able to see what is going on. If the user's data is intercepted during the initial registration, it will be much easier for someone to impersonate them. To Do Modify the functions so that if the user is registering, the $new_salt variable becomes the current salt. Add error checking. Wrap queries to mysql to protect against SQL injection attacks. SummaryThis is, I hope, an useful overview of how to protect your users' information when SSL is not available. Remember, if your site contains sensitive information, you need to use SSL, some form of public key encryption or other method to ensure the information is not leaked. References https://en.wikipedia.org/wiki/Main_Page http://www.w3schools.com/XML/xml_http.asp http://www.codingforums.com/javascript-programming/142025-xmlhttprequest-wont-work.html http://forums.xisto.com/no_longer_exists/ http://forums.xisto.com/no_longer_exists/ http://forums.xisto.com/no_longer_exists/ http://forums.xisto.com/no_longer_exists/ http://forums.devnetwork.net/viewtopic.php?f=34&t=88685 http://forums.devnetwork.net/viewtopic.php?f=34&t=92271 Regards, z.
  4. Thank you both for the warm welcome. I have already registered at that site with the same e-mail address. I do have questions about the free hosting, but I will wait till I can post in the appropriate forum and once I have collected some myCents .Regards,z.
  5. kudrat, It sounds like you have a group of 40 computers that are all going through a single Windows 2003 Server machine which is acting as a gateway to the internet. If that is the case, an easy way to stop certain computers from gaining internet access is to simply give all 40 machines static IP addresses. Then, either in your routing table or in your firewall, simply set a rule that packets going to the outside world from certain IP addresses are either dropped / blocked or just redirected into nothing. This will make it so that any person who gets on those certain machines will be unable to access the internet, but will still have access to the entire intranet. In a business environment, it is usually set for 1 person per machine. So, it should work for the majority of such cases. Regards, z.
  6. Good to meet you, Nicholai.What sort of poems / stories do you write? Do you publish them anywhere or are you hoping to do so soon? I really love reading most kinds of books, so I would really like to read any poems or stories you are willing to share.If you need help creating a site for your work, please feel free to ask.Regards,z.
  7. Hi everyone,I just wanted to introduce myself. I am zakaluka, from the USA. I've spent quite a few years as a software developer (C++, Java) and am now moving into web applications. As such, I have been teaching myself the basics of PHP and Javascript.My goal is to learn how to use the Google Web Toolkit successfully, and I am writing an application for that right now. It is related to the online MMORPG (Massively Multi-player Online Role Playing Game) Eve Online. If any of you play the or are just curious about it, feel free to ask.I am also in the process of writing a new wrapper for the wxWidgets library so that it can be used from less popular programming languages.Over the years, I've picked up a lot of general purpose knowledge that I hope to share with people here. In turn, I hope to learn more from the community here.Regards,z.
×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.