September 26, 2009

5-button mouse + firefox + mac?

when I switched to firefox 3 (in the beta testing days) I had a problem with my browser history buttons on my mac, they would not work! They worked in other browsers still, just in firefox it would give me this scroll courser called "autoscrolling".

This annoying feature is set here preferences->advanced->general. Also in about:config at general.autoscroll. I wish this could be set to one button; if middle-mouse did that --and nothing else-- I'd like that as a feature


September 17, 2009

agile keychain: decrypt in php

For those who don't know, 1password is a password manager like the one built-in to your browser; however this one, I feel, is quite secure; and it works across different browsers through plug-ins.
Agile Web Solutions originally used the key chain manager built in to Mac OS X. For a verity of reasons, they decided to make there own. They provide a good explanation of how this new key chain works, however they do not walk you through encryption or decryption of data you store in it.

This is my attempt:

there is a encryptionKeys.js file this is the first thing you will need to look at. Note it's JSON data. there is a list with two "encryption levels" The primary is encrypted with level "LS5". Each level has data and validation.

"list":[
{"validation":"U2FsdGVkX1...\u0000",
"data":"U2FsdGVkX1...\u0000",
"level":"SL3",
"identifier":"27..."},
{"validation":"U2FsdGVkX1...\u0000",
"data":"U2FsdGVkX1...\u0000",
"level":"SL5",
"identifier":"81..."}

Note:
  1. the values for validation and data are way to long, that's why I only display the beginning and end of each.
  2. I ignore the \u0000(null) at the end because it's not needed for PHP
  3. the actual file is made up of one line; I broke it up to help you read it.
  4. ls3 is designed to have a second password for your portable device that isn't as complex.

data is base64 encoded. Inside of that, the first 8 bytes of data is Salted__ This means the password needs to be salted. The salt is the next 8 bytes. The rest of the data is the "master password" cipher text.

$data = base64_decode('U2Fsd...');

Next, find the key from the password-based key derivation function(PBKDF2) which takes the password, and the salt, and creates pseudo random data suitable for a key. So you take the salt from bytes 8-16 of data, the master password you chose for your key-chain, do the standard 1,000 iterations, and request 32 bytes of output. You break that into two 8-byte parts, the key and IV for the master password cipher text. Then you take your AES-128 CBC function, and decrypt the master password.

$masterSalt = substr($data, 8, 8);
$key = pbkdf2('your password',$masterSalt,1000,32);
$masterPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, substr($key,0,16), $unsalt, MCRYPT_MODE_CBC, substr($key,16));

This master Password is 1K of random data. This random data is thrown through the following function to get the key and IV for an entry:

function OpenSSLKey ($masterPassword, $salt) {
$salted = $masterPassword . $salt;
$result = md5($salted, true);
$result = $result . md5($result . $salted, true);
$key = substr($result,0,16);
$iv = substr($result,16,16);
return array('key' => $key, 'iv' => $iv);
}

Before using this function; you will need the salt for the key you wish to decrypt. Going back to the folder you found encryptionKeys.js in, there you will find a bunch of files with UUID names. Open one you would like to decrypt, and look for encrypted. This is the encrypted portion of the entry.

{"keyID":"815...",
"locationKey":"mysite.com",
"encrypted":"U2FsdGVkX1...\u0000"
,
"typeName":"webforms.WebForm",
"openContents":{"usernameHash":"9dd...",
"passwordStrength"
:3
,
"contentsHash"
:"6556992c...",
"passwordHash"
:"5b406abcd1..."},
"location"
:"http://forum.mysite.com",
"uuid"
:"EDF5CD8C7838...",
"updatedAt"
:1227833665,
"createdAt"
:1227833665,
"title":"My account for mysite.com's forum"
,
"folderUuid"
:"C46
..."}

from there you will need to take encrypted, uudecode it, and grab the salt. THEN you can use the function from above to decrypt it.

$site_salt = substr($mysite_encrypted_data, 8, 8);
$site_cipher_data = substr($mysite_encrypted_data,16);
$itemarray = OpenSSLKey($masterPassword,$site_salt);
$masterPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, substr($key,0,16), $unsalt, MCRYPT_MODE_CBC, substr($key,16));
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $
itemarray['key'], $site_cipher_data, MCRYPT_MODE_CBC, $itemarray['iv']);