/**
* A helper class for cryptographical things like hashing passwords and so on
*
- * @author Roland Haeder <webmaster@ship-simu.org>
+ * @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007 - 2009 Roland Haeder, this is free software
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
* @license GNU GPL 3.0 or any newer version
- * @link http://www.ship-simu.org
+ * @link http://www.shipsimu.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/**
* An instance of this own clas
*/
- private static $selfInstance = null;
+ private static $selfInstance = NULL;
/**
- * Instance of the random number generator
+ * Instance of the crypto stream
*/
- private $rngInstance = null;
+ private $cryptoStreamInstance = NULL;
/**
* Salt for hashing operations
*/
private $salt = '';
- /**
- * Seperator on many places
- */
- private $seperator '|';
-
/**
* Protected constructor
*
protected function __construct () {
// Call parent constructor
parent::__construct(__CLASS__);
-
- // Clean up a little
- $this->removeNumberFormaters();
- $this->removeSystemArray();
}
/**
*
* @return $cryptoInstance An instance of this crypto helper class
*/
- public final static function createCryptoHelper () {
+ public static final function createCryptoHelper () {
// Get a new instance
$cryptoInstance = new CryptoHelper();
// Initialize the hasher
$cryptoInstance->initHasher();
+ // Attach a crypto stream
+ $cryptoInstance->attachCryptoStream();
+
// Return the instance
return $cryptoInstance;
}
*
* @return $selfInstance An instance of this crypto helper class
*/
- public final static function getInstance () {
+ public static final function getSelfInstance () {
// Is no instance there?
if (is_null(self::$selfInstance)) {
// Then get a new one
self::$selfInstance = self::createCryptoHelper();
- }
+ } // END - if
// Return the instance
return self::$selfInstance;
}
+ /**
+ * Attaches a crypto stream to this crypto helper by detecting loaded
+ * modules.
+ *
+ * @return void
+ */
+ protected function attachCryptoStream () {
+ // Do we have mcrypt loaded?
+ if ($this->isPhpExtensionLoaded('mcrypt')) {
+ // Then use it
+ $this->cryptoStreamInstance = ObjectFactory::createObjectByName('McryptStream', array($this->getRngInstance()));
+ } else {
+ // If nothing works ...
+ $this->cryptoStreamInstance = ObjectFactory::createObjectByName('NullCryptoStream');
+ }
+ }
+
/**
* Initializes the hasher for different purposes.
*
*/
protected function initHasher () {
// Initialize the random number generator which is required by some crypto methods
- $this->rngInstance = ObjectFactory::createObjectByConfiguredName('rng_class');
+ $this->setRngInstance(ObjectFactory::createObjectByConfiguredName('rng_class'));
// Generate a salt for the hasher
$this->generateSalt();
*/
private function generateSalt () {
// Get a random string from the RNG
- $randomString = $this->rngInstance->randomString();
+ $randomString = $this->getRngInstance()->randomString() . $this->createUuid();
// Get config entry for salt length
- $length = $this->getConfigInstance()->readConfig('salt_length');
+ $length = $this->getConfigInstance()->getConfigEntry('salt_length');
// Keep only defined number of characters
$this->salt = substr(sha1($randomString), -$length, $length);
}
+ /**
+ * Returns a UUID (Universal Unique IDentifier) if PECL extension uuid was
+ * found or an empty string it not.
+ *
+ * @return $uuid UUID with leading dash or empty string
+ */
+ public function createUuid () {
+ // Init empty UUID
+ $uuid = '';
+
+ // Is the UUID extension loaded? (see pecl)
+ if ((extension_loaded('uuid')) && (function_exists('uuid_create'))) {
+ // Then add it as well
+ $uuid = uuid_create();
+ } // END - if
+
+ // Return it
+ return $uuid;
+ }
+
/**
* Hashes a string with salt and returns the hash. If an old previous hash
* is supplied the method will use the first X chars of that hash for hashing
*
* @param $str Unhashed string
* @param $oldHash A hash from previous hashed string
+ * @param $withFixed Whether to include a fixed salt (not recommended in p2p applications)
* @return $hashed The hashed and salted string
*/
- public function hashString ($str, $oldHash = '') {
+ public function hashString ($str, $oldHash = '', $withFixed = TRUE) {
// Cast the string
$str = (string) $str;
// Is the old password set?
if (!empty($oldHash)) {
// Use the salt from hash, first get length
- $length = $this->getConfigInstance()->readConfig('salt_length');
+ $length = $this->getConfigInstance()->getConfigEntry('salt_length');
// Then extract the X first characters from the hash as our salt
$salt = substr($oldHash, 0, $length);
// Hash the password with salt
//* DEBUG: */ echo "salt=".$salt."/plain=".$str."<br />\n";
- $hashed = $salt . md5(sprintf($this->getConfigInstance()->readConfig('hash_mask'),
- $salt,
- $this->rngInstance->getFixedSalt(),
- $str
- ));
+ if ($withFixed === TRUE) {
+ // Use additional fixed salt
+ $hashed = $salt . md5(sprintf($this->getConfigInstance()->getConfigEntry('hash_extra_mask'),
+ $salt,
+ $this->getRngInstance()->getFixedSalt(),
+ $str
+ ));
+ } else {
+ // Use salt+string to hash
+ $hashed = $salt . md5(sprintf($this->getConfigInstance()->getConfigEntry('hash_normal_mask'),
+ $salt,
+ $str
+ ));
+ }
// And return it
return $hashed;
* Encrypt the string with fixed salt
*
* @param $str The unencrypted string
+ * @param $key Optional key, if none provided, a random key will be generated
* @return $encrypted Encrypted string
*/
- public function encryptString ($str) {
- // Init crypto module
- $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
- $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
-
- // Get key
- if ($this->getConfigInstance()->readConfig('crypt_fixed_salt') == 'Y') {
- $key = md5($this->rngInstance->getFixedSalt());
- } else {
- $key = md5($this->rngInstance->getExtraSalt());
- }
-
- // Add some "garbage" to the string
- switch ($this->rngInstance->randomNumber(0, 8)) {
- case 0:
- $garbageString = crc32($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . crc32($this->rngInstance->randomString(20));
- break;
-
- case 1:
- $garbageString = crc32($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . md5($this->rngInstance->randomString(20));
- break;
-
- case 2:
- $garbageString = crc32($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . sha1($this->rngInstance->randomString(20));
- break;
-
- case 3:
- $garbageString = md5($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . crc32($this->rngInstance->randomString(20));
- break;
-
- case 4:
- $garbageString = md5($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . md5($this->rngInstance->randomString(20));
- break;
-
- case 5:
- $garbageString = md5($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . sha1($this->rngInstance->randomString(20));
- break;
-
- case 6:
- $garbageString = sha1($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . crc32($this->rngInstance->randomString(20));
- break;
-
- case 7:
- $garbageString = sha1($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . md5($this->rngInstance->randomString(20));
- break;
-
- case 8:
- $garbageString = sha1($this->rngInstance->randomString(10)) . $this->seperator . base64_encode($str) . $this->seperator . sha1($this->rngInstance->randomString(20));
- break;
- }
-
- // Encrypt the string
- $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $garbageString, MCRYPT_MODE_ECB, $iv);
+ public function encryptString ($str, $key = NULL) {
+ // Encrypt the string through the stream
+ $encrypted = $this->cryptoStreamInstance->encryptStream($str, $key);
// Return the string
return $encrypted;
* @return $str The unencrypted string
*/
public function decryptString ($encrypted) {
- // Init crypto module
- $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
- $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
-
- // Get key
- if ($this->getConfigInstance()->readConfig('crypt_fixed_salt') == 'Y') {
- $key = md5($this->rngInstance->getFixedSalt());
- } else {
- $key = md5($this->rngInstance->getExtraSalt());
- }
-
- // Decrypt the string
- $garbageString = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_ECB, $iv);
-
- // Get the real string out
- $strArray = explode($this->seperator, $garbageString);
-
- // Does the element count match?
- assert(count($strArray) == 3);
-
- // Decode the string
- $str = base64_decode($strArray[1]);
-
- // Trim trailing nulls away
- $str = rtrim($str, "\0");
+ // Encrypt the string through the stream
+ $str = $this->cryptoStreamInstance->decryptStream($encrypted);
// Return the string
return $str;