dosbox

I showed kit dosbox. She’s now playing alleycat (sorry, ALLEYCAT.EXE) on it and we’ve all forgotten that we were actually hungry.

Of course, I did have to play a bit of Hugo’s House of Horrors – sorry, HHH.EXE.

Oh old DOS games, how awesome you are.

Storing Passwords (securly) in MySQL

Frank talks about Storing Passwords in MySQL. He does, however, miss something that’s really, really important. I’m talking about the salting of passwords.

If I want to find out what  5d41402abc4b2a76b9719d911017c592 or 015f28b9df1bdd36427dd976fb73b29d MD5s mean, the first thing I’m going to try is a dictionary attack (especially if i’ve seen a table with only user and password columns). Guess what? A list of words and their MD5SUMS can be used to very quickly find what these hashes represent.

I’ll probably have this dictionary in a MySQL database with an index as well. Try it yourself – you’ll probably find a dictionary with the words “hello” and “fire” in it to help. In fact, do this:

mysql> create table words (word varchar(100));
Query OK, 0 rows affected (0.13 sec)
mysql> load data local infile ‘/usr/share/dict/words’ into table words;
Query OK, 98326 rows affected (0.85 sec)
Records: 98326  Deleted: 0  Skipped: 0  Warnings: 0

mysql> alter table words add column md5hash char(32);
Query OK, 98326 rows affected (0.39 sec)
Records: 98326  Duplicates: 0  Warnings: 0

mysql> update words set md5hash=md5(word);
Query OK, 98326 rows affected (3.19 sec)
Rows matched: 98326  Changed: 98326  Warnings: 0
mysql> alter table words add index md5_idx (md5hash);
Query OK, 98326 rows affected (2.86 sec)
Records: 98326  Duplicates: 0  Warnings: 0
mysql> select * from words where md5hash=’5d41402abc4b2a76b9719d911017c592′;
+——-+———————————-+
| word  | md5hash                          |
+——-+———————————-+
| hello | 5d41402abc4b2a76b9719d911017c592 |
+——-+———————————-+
1 row in set (0.11 sec)
mysql> select * from words where md5hash=’015f28b9df1bdd36427dd976fb73b29d’;
+——+———————————-+
| word | md5hash                          |
+——+———————————-+
| fire | 015f28b9df1bdd36427dd976fb73b29d |
+——+———————————-+
1 row in set (0.00 sec)
$EXCLAMATION I hear you go.

Yes, this is not a good way to “secure” passwords. Oddly enough, people have known about this for a long time and there’s a real easy  solution. It’s called salting.

Salting is prepending a random string to the start of the password when you store it (and when you check it).

So, let’s look at how our new password table may look:

mysql> select * from passwords;
+——+——–+———————————-+
| user | salt   | md5pass                          |
+——+——–+———————————-+
| u1   | ntuk24 | ce6ac665c753714cb3df2aa525943a12 |
| u2   | drc,3  | 7f573abbb9e086ccc4a85d8b66731ac8 |
+——+——–+———————————-+
2 rows in set (0.00 sec)
As you can see, the MD5s are different than before. If we search these up in our dictionary, we won’t find a match.

mysql> select * from words where md5hash=’ce6ac665c753714cb3df2aa525943a12′;
Empty set (0.01 sec)

instead, we’d have to get the salt and do an md5 of the salt and the dictionary word and see if the md5 matches. Guess what, no index for that! and with all the possible values for salt, we’ve substantially increased the problem space to construct a dictionary (i won’t go into the maths here).

mysql> create view v as select word, md5(CONCAT(‘ntuk24′,word)) as salted from words;
Query OK, 0 rows affected (0.05 sec)

mysql> select * from v where salted=’ce6ac665c753714cb3df2aa525943a12’;
+——-+———————————-+
| word  | salted                           |
+——-+———————————-+
| hello | ce6ac665c753714cb3df2aa525943a12 |
+——-+———————————-+
1 row in set (2.04 sec)

mysql> create or replace view v as select word, md5(CONCAT(‘drc,3′,word)) as salted from words;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from v where salted=’7f573abbb9e086ccc4a85d8b66731ac8’; +——+———————————-+
| word | salted                           |
+——+———————————-+
| fire | 7f573abbb9e086ccc4a85d8b66731ac8 |
+——+———————————-+
1 row in set (2.12 sec)

So we’ve gone from essentially instantaneous retreival, to now taking about 2 seconds. Even if I assume that one of your users is going to be stupid enough to have a dictionary password, It’s going to take me 2 seconds to check each user – as the salt is different for each user! So it could take me hours just to find that user. Think about how many users are in your user table – with 1000 users, it’s over 1/2hr. For larger systems, it’s going to be hours.

Tapioca VoIP happiness

Tapioca – TapiWiki

and specifically, the Landell front end as it supports the use of a http proxy.

I’ve been able to call Kit and chat while I’ve been on the road this time. Means we get to avoid nasty GSM roaming charges (or any charges) and even though there’s some lag (like a second or so) and the voice quality isn’t brilliant – using Landell/Tapioca and Google Talk on her end means we get to stay in touch without feeling guilty about massive phone bills.

I totally heart free software.

Welcome to Beijing (day 1)

I’ve just come back from lunch. I’ve managed to eat Chinese food, in China, with chopsticks and not totally embarass myself. Ate some new food, new vegetables and a seemingly different type of seaweed than I have eaten before. It tasted good though. I even think Kit would have liked some of it (once she got over the fact that it looked different and some things were green things).
I arrived safely after a flight that was fine (except for getting up rather early to get to Sydney to then take a sane timed flight). Beijing seems to be a bit like the firefly world, except with less flying cars. You’ve got heaps of stuff in English and Chinese. It could be really interesting to live here and experience things.

There’s a national English language newspaper which is fairly up to date on world events – the fact that our dear Mr Howard is going to go to the election seems to be news here! It’s not packed with local news, which would be interesting to read (although I think I’ll have to learn to read first).

The hotel is a short walk from the office (down the street, across the road). Oh, the roads are at least 7 lanes – they’re big!

Hotel is pretty nice, probably about half the price of what I’d expect to pay back home. Breakfast was good – some totally delicious watermelon. Honestly thinking of just having watermelon for breakfast tomorrow :)

Although it’s rather obvious that the hotel is aimed at western visitors. At breakfast you could only really tell you’re in China by: looking out the front window at all the Chinese writing or looking at the waiters and waitresses and noticing they all a) spoke Chinese to each other and b) were Chinese. About 5 languages before my first coffee – what a way to start the day!

At some point I’m going to have to have some Chinese tea – it seems like a real obvious must-do. Although maybe I should give in at some point and buy coffee from starbucks as well….