<?

/*/
	File:  encrypt.phi
	© 2007 Windshields To Go - All rights reserved.
	Purpose:  Encrypt/Decrypt text settings
	Created:  08/29/2007 - Jeremy
	Modification History:
		· 01/27/2008 - Nathan- needless reformattings
		· mm/dd/yyyy - name - comment
/*/


	$gblEncryptDefaultKey = ":2[34l|`jLK~J3,5@lk_";
	$gblEncryptDefaultIv = "29988654";

	
//-------------------------------------------------------------------------
// Encrypt a KEY=VALUE array with the default global keys into a url-safe string.
//-------------------------------------------------------------------------
function encrypt_settings( &$data ) {

	global $gblEncryptDefaultKey, $gblEncryptDefaultIv;

	return encrypt_settings_with_key($data, $gblEncryptDefaultKey, $gblEncryptDefaultIv);

} // encrypt_settings()


//-------------------------------------------------------------------------
// Decrypt a string of encoded/encrypted values into a KEY=VALUE array.
//-------------------------------------------------------------------------
function decrypt_settings($text) {

	global $gblEncryptDefaultKey, $gblEncryptDefaultIv;

	return decrypt_settings_with_key( $text, $gblEncryptDefaultKey, $gblEncryptDefaultIv );

} // decrypt_settings()


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


//-------------------------------------------------------------------------
// Encrypt an array of KEY=VALUE settings into an encrypted/encoded string
//-------------------------------------------------------------------------
function encrypt_settings_with_key( &$data, $key, $iv ) {
	$text = "";

	/// the compiled string
	foreach( $data as $name => $value ) {
		if($text != "") $text .= "&";
		$text .= urlencode($name);
		$text .= "=";
		$text .= urlencode($value);
	}

	/// add in a CRC prefix
	$checksum_text = base_convert(crc32($text), 10, 36);
	$text = $checksum_text."|".$text;

	/// and a random postfix to achieve the correct block size
	$padding = "|".substr("00000000".$checksum_text, -7);
	$text .= substr($padding, 0, 8 - (strlen($text) % 8));

	/// encrypt it
	return urlsafe_base64encode(encrypt_data($text, $key, $iv));		

} // encrypt_settings_with_key()


//-------------------------------------------------------------------------
// Decrypt a string of encoded/encrypted values to a KEY=VALUE array
//-------------------------------------------------------------------------
function & decrypt_settings_with_key( $text, $key, $iv ) {

	$nullvalue = null;
	$data = array();

	/// decode and decrypt
	$extended_content = decrypt_data(urlsafe_base64decode($text), $key, $iv);

	/// parse out the checksum and any padding
	$extended_segments = explode('|', $extended_content);
	if(count($extended_segments) < 2) return $nullvalue;
	$checksum = $extended_segments[0];
	$content = $extended_segments[1];

	/// validate the checksum
	if( base_convert(crc32($content), 10, 36) != $checksum ) return $nullvalue;

	/// chop it up
	$content_nvpairs = explode('&', $content);

	/// chop up the string and rebuild the array
	foreach( $content_nvpairs as $nvstring ) {
		$nv = explode('=', $nvstring, 2);
		$name = urldecode(isset($nv[0]) ? $nv[0] : "");
		$value = urldecode(isset($nv[1]) ? $nv[1] : "");
		$data[$name] = $value;
	}

	/// array (by reference)
	return $data;

} // decrypt_settings_with_key()


//-------------------------------------------------------------------------
// Encode using a modified Base64 so that the data is 'safe' for a GET request
//-------------------------------------------------------------------------
function urlsafe_base64encode( $string ) {

  $data = base64_encode($string);
  $data = str_replace( array('+','/','='), array('-','_','.'), $data );

  return $data;

} // urlsafe_base64encode()

//-------------------------------------------------------------------------
// Decode from a modified Base64
//-------------------------------------------------------------------------
function urlsafe_base64decode( $string ) {

  $data = str_replace( array('-','_','.'), array('+','/','='), $string );
  $mod4 = strlen($data) % 4;
  if( $mod4 ) {
	 $data .= substr('====', $mod4);
  }
  return base64_decode($data);

} // urlsafe_base64decode()


//-------------------------------------------------------------------------
// Blowfish encryption cipher.
//-------------------------------------------------------------------------
function encrypt_data( $text, $key, $iv ) {

	$cipher = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'cbc', '');
	mcrypt_generic_init($cipher, $key, $iv);
	$encrypted = mcrypt_generic($cipher, $text);
	mcrypt_generic_deinit($cipher);

	// Return the encrypted
	return $encrypted;

} // encrypt_data()


//-------------------------------------------------------------------------
// Blowfish decryption cipher.
//-------------------------------------------------------------------------
function decrypt_data( $encrypted, $key, $iv ) {

	$cipher = mcrypt_module_open( MCRYPT_BLOWFISH, '', 'cbc', '' );
	mcrypt_generic_init( $cipher, $key, $iv );
	$decrypted = mdecrypt_generic( $cipher, $encrypted );
	mcrypt_generic_deinit( $cipher );

	/// all done
	return $decrypted;

} // decrypt_data()


?>