Jump to content

Destramic

Members
  • Posts

    969
  • Joined

  • Last visited

Posts posted by Destramic

  1. hey guys i've fiddled about with my mysql datadir and i've buggered it! what have i done wrong please :

    C:\WINDOWS\system32>net start mysql57
    The service is starting or stopping.  Please try again later.
    

    so my - my.ini and data folder was in

    C:\ProgramData\MySQL\MySQL Server 5.7
    

    i copied all the files/folders into

    R:\localhost\mysql
    

    stopped mysql and edited the my.ini inside the C:\ProgramData\MySQL\MySQL Server 5.7 directory.

     

     

    edited: under [mysqld]

    basedir=R:/localhost/mysql
    datadir=R:/localhost/mysql/Data
    

    i have no error log and now i'm completely stuck....i'd like to know how it is done, worst comes to the worst i can just reinstall mysql 5.7 and leave it alone :)

     

    thank you

     

     

     

     

  2. I haven't read the entire code, but I'm fairly sure you can make it a lot simpler and more robust if you use the official phpDocumentor parser instead of implementing your own (by the way, it's parse, not “phase”).

     

    thanks for tip...on reflection of my attemp above i can see it's very poor...i'll give phpDocumentor a look :)

  3. hey guys,

     

    i discovered annotation validation recently and liked how easy it is to validate general class' and form enitys...so i decided i'd write my own script...i don't normally ask for feedback, but as i jumped into the deep end creating an annotation handler, with no experience of using/writing one, i'd like to ask if i could get some general feedback please.

     

    i've read some documation on symfony2 and phpdoc but that's about it.

     

    annotation reader: reads and gathers comments left for properties and mehtods as well as namespaces

    <?php
    
    namespace Annotation;
    
    use Exception;
    use ReflectionClass;
    use ReflectionProperty;
    use ReflectionMethod;
    use ReflectionFunction;
    
    class Reader
    {	
    	private $class_name;
    	
    	private $properties = array();
    	private $methods    = array();
    	private $namespaces = array();
    	
    	public function read($object)
    	{
    		$reflector        = new ReflectionClass($object);
    		$this->class_name = $reflector->getShortName();
    		
    		foreach ($reflector->getProperties() as $property)
    		{
    			$name     = $property->getName();
    			$property = $reflector->getProperty($name);
    			
    			$property->setAccessible(true);
    			
    			$value  = $property->getValue($object);
    			$tags   = new Phaser($property->getDocComment());
    			
    			$this->properties[$name] = array(
    					'tags'  => $tags->phase(),
    					'value' => $value
    			);
    		}
    		
    		foreach ($reflector->getMethods() as $method)
    		{
    			$name   = $method->getName();
    			$method = $reflector->getMethod($name);
    			
    			$method->setAccessible(true);
    
    			$tags        = new Phaser($method->getDocComment());
    			$parameters  = array();
    			
    		 	foreach ($method->getParameters() as $parameter) 
    		 	{
            		$parameters[] = strtolower($parameter->name);
        		}
        		
    			$this->methods[$name] = array(
    					'tags'        => $tags->phase(),
    					'parameters'  => $parameters
    			);
    		}
    		
    		$contents = file_get_contents($reflector->getFileName());
    		
    		preg_match_all('#use\s+(?P<namespace>[\w\\\]+)(?:\s+as\s+(?P<alias>[\w]+))?#i', $contents, $matches);
    				
    		for ($i = 0; $i < count($matches[0]); $i++)
    		{
    			$alias     = strtolower($matches['alias'][$i]);
    			$namespace = strtolower($matches['namespace'][$i]);
    			
    			if (empty($alias))
    			{
    				$alias = $namespace;
    			}
    			
    			$this->namespaces[$alias] = $namespace;
    		}
    		
    		return $this;
    	}
    	
    	public function get_class_name()
    	{
    		return $this->class_name;
    	}
    	
    	public function get_properties()
    	{
    		return $this->properties;
    	}
    	
    	public function get_property($property)
    	{
    		if (isset($this->properties[$property]))
    		{
    			return $this->properties[$property];
    		}
    		
    		return null;
    	}
    	
    	public function get_methods()
    	{
    		return $this->methods;
    	}
    	
    	public function get_method($method)
    	{
    		if (isset($this->methods[$method]))
    		{
    			return $this->methods[$method];
    		}
    		
    		return null;
    	}
    	
    	public function get_namespaces()
    	{
    		return $this->namespaces;
    	}
    }
    

    annotation phaser: used in the reader, this phases the tags and returns a nice array?

    <?php
    
    namespace Annotation;
    
    class Phaser
    {	
    	private $annotation;
    	
    	private $tags = array();
    	
    	private $patterns = array(
    		'vars_params' => '@(?P<tag>var|param)\s+(?:\\$(?P<parameter>\w+)\s+)?(?P<type>\S+) *(?P<description>.*)?',
    	    'return'      => '@return\s+(?P<type>\S+) *(?P<description>.*)?'
    	);
    	
    	public function __construct($annotation)
    	{
    		$this->annotation = $annotation;
    	}
    	
    	public function phase()
    	{
    		foreach ($this->patterns as $tag => $pattern)
    		{
    			$this->$tag();
    		}
    		
    		return $this->tags;
    	}
    	
    	private function vars_params()
    	{
    		$vars_params = $this->match($this->patterns['vars_params']);
    		
    		$vars   = array();
    		$params = array();
    		
    		if ($vars_params)
    		{
    			for ($i = 0; $i < count($vars_params[0]); $i++)
    			{
    				$tag       = $vars_params['tag'][$i] . 's';
    				$parameter = strtolower($vars_params['parameter'][$i]);
    				
    				$data = array(
    						'type'       => $vars_params['type'][$i],
    					    'descrption' => $vars_params['description'][$i]
    				);
    				
    				if ($tag === 'vars')
    				{
    					${$tag}[] = $data;
    				}
    				else 
    				{
    					${$tag}[$parameter][] = $data;
    				}
    			}
    		}
    
    		if (count($vars) > 0)
    		{
    			$this->tags['vars'] = $vars;
    		}
    		else if (count($params) > 0)
    		{
    			$this->tags['params'] = $params;
    		}
    	}
    	
    	private function return()
    	{
    		$return = $this->match($this->patterns['return']);
    
    		if ($return)
    		{
    			$this->tags['return'] = array(
    					'type'        => $return['type'][0],
    			   	 	'description' => $return['description'][0]
    			);
    		}
    	}
    	
    	private function match($pattern)
    	{
    		$pattern = '#' . $pattern . '#';
    	
    		if (preg_match_all($pattern, $this->annotation, $matches))
    		{
    			return $matches;
    		}
    	
    		return null;
    	}
    }	
    

    ok so i was a little confused to how the annotation validation process is kicked off, after a lot of thinking all i could come up was this:

     

    annotation: where my class is injected so it can be validated on __call  & __set

    <?php
    
    namespace Annotation;
    
    use Exception;
    use ReflectionClass;
    
    class Annotation
    {	
    	private $object;
    	private $reader;
    	private $validator;
    	
    	public function __construct($object)
    	{
    		if (!is_object($object))
    		{
    			throw new Exception('Validator: Unkown class object.');
    		}
    		
    		$this->object    = $object;
    		$reader          = new Reader;
    		$this->reader    = $reader->read($object);
    		$this->validator = new Validator($reader);
    	}
    
    	public function __set($property, $value)
    	{
    		$this->validator->set_property($property)
    		                ->set_value($value)
    		                ->validate_property()
    		                ->reset();
    		
    		$this->object->$property = $value;
    	}
    	
    	public function __get($property)
    	{
    		return $this->object->$property;
    	}	
    	
    	public function __call($method, $arguments = array())
    	{
    		$this->validator->set_method($method)
    		                ->set_arguments($arguments)
    		                ->validate_parameters();
    		
    		$return = call_user_func_array(array(
    				$this->object, 
    				$method), 
    				$arguments
    		);
    		
    		$this->validator->set_return($return)
    		                ->validate_return()
    		                 ->reset();
    		
    		return $return;
    	}
    	
    	// entitys 
    	public function validate()
    	{
    		
    	}
    }
    

    and finally my validator, which validates propery/method var, parma, return, constraints

    <?php
    
    namespace Annotation;
    
    use Exception;
    
    class Validator
    {	
    	private $property;
    	private $method;
    	private $value;
    	
    	private $arguments = array();
    	
    	private $reader;
    
    	public function __construct(Reader $reader)
    	{
    		$this->reader = $reader;
    	}
    	
    	public function validate_parameters()
    	{
    		$method = $this->get_method();
    		
    		if (empty($method['tags']['params']))
    		{
    			return $this;
    		}
    		
    		$i         = 0;
    		$arguments = $this->get_arguments();
    		
    		foreach ($method['parameters'] as $parameter)
    		{
    			if (!isset($method['tags']['params'][$parameter]))
    			{
    				continue;
    			}
    			
    			foreach ($method['tags']['params'][$parameter] as $tag)
    			{
    				$type      = $tag['type'];
    				$value     = null;
    				
    				if (isset($arguments[$i]))
    				{
    					$value = $arguments[$i];
    				}
    					
    				if ($match = $this->is_namespace($type))
    				{
    					if (!$this->validate_namespace($match['namespace']))
    					{
    						throw new Exception(sprintf("Validator: Parameter $%s must instance of %s.", $parameter, $match['namespace']));
    					}
    				}
    				else if ($match = $this->is_constraint($type))
    				{
    					$response = $this->validate_constraint($match['alias'], $match['method'], $match['arguments'], $value);
    					
    					if ($response !== true)
    					{
    						throw new Exception(sprintf("Validator: Parameter $%s %s", $parameter, $response));
    					}
    				}
    				else
    				{
    					if (!$this->is_valid_data_type($type, $value))
    					{
    						throw new Exception(sprintf("Validator: Parameter $%s must be %s type.", $parameter, $type));
    					}
    				}
    			}
    			
    			$i++;
    		}
    		
    		return $this;
    	}
    
    	public function validate_return()
    	{
    		$method = $this->get_method();
    
    		if (!isset($method['tags']['return']))
    		{
    			return $this;
    		}
    		
    		$type  = $method['tags']['return']['type'];
    		$value = $this->get_return();
    		
    		if (!$this->is_valid_data_type($type, $value))
    		{
    			throw new Exception(sprintf("Validator: Method %s must return %s type.", $this->method, $type));
    		}
    	
    		return $this;
    	}
    	
    	public function validate_property()
    	{
    		$property = $this->get_property();
    
    		if (!isset($property['tags']['vars']))
    		{
    			return $this;
    		}
    		
    		$value = $this->get_value();
    		
    		foreach ($property['tags']['vars'] as $tag)
    		{
    			$type = $tag['type'];
    			
    			if ($match = $this->is_namespace($type))
    			{
    				if (!$this->validate_namespace($match['namespace']))
    				{
    					throw new Exception(sprintf("Validator: Property $%s must instance of %s.", $parameter, $match['namespace']));
    				}
    			}
    			else if ($match = $this->is_constraint($type))
    			{
    				$response = $this->validate_constraint($match['alias'], $match['method'], $match['arguments'], $value);
    					
    				if ($response !== true)
    				{
    					throw new Exception(sprintf("Validator: Property $%s %s", $this->property, strtolower($response)));
    				}
    			}
    			else
    			{
    				if (!$this->is_valid_data_type($type, $value))
    				{
    					throw new Exception(sprintf("Validator: Property $%s must be %s type.", $this->property, $type));
    				}
    			}
    		}
    		
    		return $this;
    	}
    	
    	private function is_valid_data_type($type, $value)
    	{
    		$type = explode('|', $type);
    		
    		foreach ($type as $type)
    		{
    			if (strcasecmp($type, gettype($value)) === 0)
    			{
    				return true;
    			}
    		}
    		
    		return false;
    	}
    	
    	private function validate_constraint($alias, $method, $arguments, $value)
    	{
    		$alias      = strtolower($alias);
    		$namespaces = $this->reader->get_namespaces();
    		
    		if (!array_key_exists($alias, $namespaces))
    		{
    			throw new Exception(sprintf("Validator: Uknown constraint %s.", $type));
    		}
    		
    		$class = $namespaces[$alias];
    		
    		if (!class_exists($class))
    		{
    			throw new Exception(sprintf("Validator: Unknown constraint %s."), $class);
    		}
    		
    		$constraint = new $class;
    		$method     = $method;
    		
    		if (!is_array($arguments))
    		{
    			$arguments = array($arguments);
    		}
    		
    		$constraint = call_user_func_array(array($constraint, $method), $arguments);
    			
    		$constraint->set_value($value);
    		
    		if ($constraint->is_valid())
    		{
    			return true;
    		}
    		
    		return $constraint->get_error_message();
    	}
    	
    	private function validate_namespace($namespace, $parameter)
    	{
    		$namespace = strtolower($namespace);
    		
    		$aliases = $this->reader->get_namespaces();
    		
    		if (array_key_exists($namespace, $aliases))
    		{
    			$namespace = $aliases[$namespace];
    		}
    		
    		if ($value instanceof $namespace)
    		{
    			return true;
    		}
    		
    		return false;
    	}
    	
    	private function is_namespace($string)
    	{
    		$types = array(
    				'booleon',
    				'integer',
    				'double',
    				'string',
    				'array',
    				'object'.
    				'resource',
    				'null'
    		);
    		
    		if (!in_array(strtolower($string), $types) && preg_match('#^(?P<namespace>(?:\\\\)?[\w]+(?:\\\\[\w]+)*)$#', $string, $match))
    		{
    			return $match;
    		}
    		
    		return false;
    	}
    	
    	private function is_constraint($string)
    	{
    		if (preg_match('#^(?P<alias>\w+)\\\(?P<method>\w+)\((?P<arguments>.*)\)$#', $string, $match))
    		{
    			return $match;
    		}
    		
    		return false;
    	}
    	
    	public function set_method($method)
    	{
    		$this->method = $method;
    		
    		return $this;
    	}
    	
    	public function get_method()
    	{
    		if (is_null($this->method))
    		{
    			throw new Exception('Validator: Method has not been set.');
    		}
    		else if (!$method = $this->reader->get_method($this->method))
    		{
    			throw new Exception(sprintf('Unkown method %s in a class %s.', $this->method, $this->reader->get_class_name()));
    		}
    		
    		return $method;
    	}
    	
    	public function set_arguments($arguments)
    	{
    		$this->arguments = $arguments;
    		
    		return $this;
    	}
    	
    	public function get_arguments()
    	{
    		if (!is_array($this->arguments))
    		{
    			throw new Exception('Validator: Arguments must be an array.');
    		}
    		
    		return $this->arguments;
    	}
    	
    	public function get_property()
    	{
    		if (is_null($this->property))
    		{
    			throw new Exception('Validator: Property has not been set.');
    		}
    		else if (!$property = $this->reader->get_property($this->property))
    		{
    			throw new Exception(sprintf('Unkown property $%s in a class %s.', $this->property, $this->reader->get_class_name()));
    		}
    		
    		return $property;
    	}
    	
    	public function set_property($property)
    	{
    		$this->property = $property;
    		
    		return $this;
    	}
    	
    	public function set_value($value)
    	{
    		$this->value = $value;	
    		
    		return $this;
    	}
    	
    	public function get_value()
    	{
    		return $this->value;
    	}
    	
    	public function set_return($return)
    	{
    		$this->return = $return;
    		
    		return $this;
    	}
    	
    	public function get_return()
    	{
    		return $this->return;
    	}
    	
    	public function reset()
    	{
    		$this->method    = null;
    		$this->arguments = array();
    		$this->value     = null;
    		$this->return    = null;
    		
    		return $this;
    	}
    }
    

    how my annotation validation works on a test class (Person)

    use Validator\Constraint as Assert;
    
    class Person
    {
    	/**
    	 * @var Assert\Not_Blank()
    	 * @var string
    	 **/
    	public $name;
    	
    	/**
    	 * @var Assert\Not_Blank()
    	 * @var integer
    	 **/
    	public $age;
    	
    	/**
    	 * @var Assert\Email_Address()
    	 * @var string
    	 **/
    	public $email_address;
    	
    	/**
    	 * @return array
    	 **/
    	public function get_credentials()
    	{
    		// working 
    		return array(
    				'name'          => $this->name,
    				'age'           => $this->age,
    				'email_address' => $this->email_address
    		);
    	}
    }
    
    use Annotation\Annotation as Annotation;
    
    $person = new Annotation(new Person);
    $person->name = 'John Doe';
    $person->age  = 101;
    $person->email_address = '[email protected]';
    
    print_r($person->get_credentials());
    

    its all singing and dancing, although there is still a lot to do like implment a gernal validation for single/multiple entitys and tidying up....but i really don't know if i've gone around the right way of doing this...have i over thought it?

     

    and i know its a lot to look at but any feedback/criticism would be appreciated

     

     

    thakn you!

  4. ok i see now so the “additional data" is used to reinforce the encryption?...should i be change the string depeding on what im encrypting. ie. if i'm encrypting users information then the user would have a private key and that would be used for my “additional data" as i put it.

     

    understood regarding throwing exception...due to the nature of the script it should just return fatal error.

     

    i've also been looking into symfony's annoations so yeah i think i'm going to writes something to validate type hinting

     

    but thank you for the brilliant feedback...much appreciated

  5. ok so my class here is good to encrypt everything really...when looking at https://paragonie.com/book/pecl-libsodium/read/09-recipes.md it makes you think you need to make a encryption and decryption class especially for cookies and passwords

     

    thank you for all the great information i'll definitly be keeping this in mind

     

     

    • confidentiality without integrity/authenticity (not recommended) ⇒ classical encryption, e. g. AES-CBC
    • confidentiality with integrity/authenticity ⇒ authenticated encryption, e. g. ChaCha20 + Poly1305
    • integrity/authenticity without confidentiality ⇒ HMAC
    • passwords ⇒ password hash algorithm, e. g. bcrypt; optionally encryption

     

    also here my class updated from your suggestions

    <?php
    
    namespace Encryption;
    
    use Exception;
    
    class Encryption
    {
    	private $_keys_directory;
    	
    	private $_secret_key;
    	private $_public_key;
    	
    	public function __construct($keys_directory)
    	{
    		$this->_keys_directory = $keys_directory;
    	
    		if (!extension_loaded('libsodium'))
    		{
    			throw new Exception('Encryption: PHP libsodium extension not loaded.');
    		}
    	}
    	
    	public function encrypt($data)
    	{
    		$nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
    	  
    		$secret_key = $this->secret_key();
    		
    		if (!$secret_key)
    		{
    			return false;
    		}
    		
    		$ciphertext = \Sodium\crypto_aead_chacha20poly1305_encrypt(
    		    $data,
    		    $this->additional_data(),
    		    $nonce,
    		    $this->secret_key()
    		);
    
    		return  base64_encode($nonce) . ':' . base64_encode($ciphertext);
    	}
    	
    	public function decrypt($ciphertext)
    	{
    		$ciphertext = $this->parse_ciphertext($ciphertext);
    		$secret_key = $this->secret_key();
    		
    		if (!$ciphertext || !$secret_key)
    		{
    			return false;
    		}
    		
    		list($nonce, $ciphertext) = $ciphertext;
    
    		$decryption = \Sodium\crypto_aead_chacha20poly1305_decrypt(
    		    $ciphertext,
    		    $this->additional_data(),
    		    $nonce,
    		    $this->secret_key()
    		);
    
    		return $decryption;
    	}
    	
    	private function secret_key()
    	{
    		if (!is_null($this->_secret_key))
    		{
    			return $this->_secret_key;
    		}
    	
    		$this->_secret_key = $this->get_key('secret.key');
    	
    		return $this->_secret_key;
    	}
    	
    	private function public_key()
    	{
    		if (!is_null($this->_public_key))
    		{
    			return $this->_public_key;
    		}
    	
    		$this->_public_key = $this->get_key('public.key');
    	
    		return $this->_public_key;
    	}
    	
    	private function get_key($filename)
    	{
    		$filename = $this->_keys_directory . '/' . $filename;
    				
    		if (!is_readable($filename))
    		{
    			return false;
    		}
    				
    		return base64_decode(file_get_contents($filename));
    	}
    	
    	private function parse_ciphertext($ciphertext)
    	{
    		$ciphertext = explode(':', $ciphertext);
    
    		if (count($ciphertext) !== 2)
    		{
    			return false;
    		}
    		
    		return array(
    			base64_decode($ciphertext[0]),
    			base64_decode($ciphertext[1])
    		);
    	}
    	
    	private function additional_data()
    	{
    		return 'fba05a681b7606c57d6218d4cca387f5cd4f8e0ae098cb4d9b7e';
    	}
    }
    

    thank you

  6. replace

    strpos($_GET['nav'], "/")
    

    with

    strstr($_GET['nav'], '/')
    

    tried to tidy it up also, you may want to use require_once

    if (isset($_GET['nav'])) 
    {
    	$nav = $_GET['nav'];
    	
    	if (strstr($nav, '/'))
    	{
    	    $directory = substr(str_replace('..', '', $nav), 0, strpos($nav, "/")) . "/";
    	    $file       = substr(strrchr($nav, "/"), 1);
    	    
    	    if (file_exists($directory . $file . ".php")) 
    		{
    	    	require_once($directory . $file . ".php");
    		} 
    		else 
    		{
    	    	require_once("error.php");
    		}
    	} 
    	else 
    	{
    	    if (file_exists(basename($nav) . ".php"))
    		{
    	    	require_once (basename($nav).".php");
    		} 
    		else 
    		{
    	    	require_one("error.php");
    		}
    	}
    } 
    else
    {
       require_once ("default.php");
    }
    

    personally i'd probably use something like this

    switch ($_GET['nav'])
    {
    	case 'news';
    		$page = 'news.php'; // ?nav=news
    	break;
    	
    	default:
    		$page = 'error.php';
    	break;
    }
    
    require_once $page;
    

    hope this helps

  7.  

    • The class architecture doesn't really make sense. There should be one class which takes care of all the low-level cryptography. If you call the libsodium functions in the different subclasses for encrypting sessions, cookies etc., you'll quickly end up with duplicate code. From a cryptography standpoint, there's no difference between encrypting a session and encrypting a cookie. It's just different data

      

    ummm when looking at https://paragonie.com/book/pecl-libsodium/read/09-recipes.md

    i see they encrypt and decrypt thier cookies different to how i've done my text class...also i see versions of encrypting passwords and verifying so i assumed i'd no longer need password_verfiy() and password_hash() functons...my plan was to make a session_cookie class which extends encryption_abstract same with password...so this one class is all i need for all encryptions? :confused:

     

     

     

    • Get rid of the try statements. Not only are they useless and make you lose important information like the error location and the stack trace. They defeat the whole purpose of exceptions, because now you're back having to check return values. It's particularly strange when you throw an exception and then immediately catch it.
    • A low-level cryptography class should not do any JSON-encoding. In fact, you're making the data ambiguous, because it's no longer clear whether it's actually a JSON document or just happens to look like the JSON format. Who says that [42] is a JSON array? Maybe it's supposed to be a literal pair of brackets with a number. Do all the encoding and decoding outside of the class.
    • The angle brackets <> in my format were meant for you, the reader. The actual format is just a colon-separated list of parameters.
    • Since you now use a fixed algorithm, there's no need for a version. If you still want to use versions, don't compare them with < or >, because those operators don't understand the semantics of version numbers. For example, "2.0.0" is considered greater than "10.0.0". It also doesn't really make sense to reject a ciphertext just because there was an unrelated change somewhere in the libsodium library.
    • Your “additional data” parameter for the AEAD algorithm is currently a long random string. This makes no sense. The purpose of the parameter is that you can split the input into two parts: a secret part which should be encrypted and protected from manipulation, and a non-secret part which should only be protected from manipulation. If you don't need this (which is most of the time), simply use an empty string as the additional data.
    • The naming isn't ideal. “get_encryption” and “get_decryption” don't make much sense. When you remove the JSON stuff, you can probably get rid of get_decryption() altogether. And get_encryption() should be renamed to something like parse_ciphertext().

     

    haha last night when looking at:

     <version identifier>:<Base64-encoded nonce>:<Base64-encoded ciphertext>
    

    i made it so the encryption returned as version:nonce:ciphertext, but when i looked at it again today i thought he might mean with <>....but all that been said i'll change my class with all your possitive comments in mind.

     

    thank you much appreciated :happy-04:

  8. thank you for the good information...i took what you said onboard and here is what i made

    class Text extends Encryption_Abstract
    {
    	public function encrypt($message)
    	{
    		if (is_array($message))
    		{
    			$message = json_encode($message);
    		}
    		
    		$nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
    	  
    		$ciphertext = \Sodium\crypto_aead_chacha20poly1305_encrypt(
    		    $message,
    		     $this->additional_data(),
    		    $nonce,
    		    $this->secret_key()
    		);
    
    	    return '<' . $this->version() . '>:<' . base64_encode($nonce) . '>:<' . base64_encode($ciphertext) . '>';
    	}
    	
    	public function decrypt($encryption)
    	{
    		$encryption = $this->get_encryption($encryption);
    
    		$decryption = \Sodium\crypto_aead_chacha20poly1305_decrypt(
    		    $encryption['ciphertext'],
    		    $this->additional_data(),
    		    $encryption['nonce'],
    		    $this->secret_key()
    		);
    
    		return $this->get_decryption($decryption);
    	}
    }
    

    abstract - so it can be used for gloabls(session, cookie) and passwords

    abstract class Encryption_Abstract
    {
    	private $_keys_directory;
    	
    	private $_secret_key;
    	private $_public_key;
    	
    	public function __construct($keys_directory)
    	{
    		$this->_keys_directory = $keys_directory;
    		
    		if (!extension_loaded('libsodium')) 
    		{
    			throw new Exception('Encryption: PHP libsodium extension not loaded.');
    		}
    	}
    	
    	protected function secret_key()
    	{
    		if (!is_null($this->_secret_key))
    		{
    			return $this->_secret_key;
    		}
    
    		$this->_secret_key = $this->get_key('secret.key');
    		
    		return $this->_secret_key;
    	}
    	
    	protected function public_key()
    	{
    		if (!is_null($this->_public_key))
    		{
    			return $this->_public_key;
    		}
    		
    		$this->_public_key = $this->get_key('public.key');
    		
    		return $this->_public_key;
    	}
    	
    	protected function additional_data()
    	{
    		return 'fba05a681b7606c57d6218d4cca387f5cd4f8e0ae098cb4d9b7e';
    	}
    	
    	protected function version()
    	{
    		$libsodium = new ReflectionExtension('libsodium');
    		
    		return $libsodium->getVersion();
    	}
    	
    	private function get_key($filename)
    	{
    		try 
    		{
    			$filename = $this->_keys_directory . '/' . $filename;
    			
    			if (!is_readable($filename))
    			{
    				throw new Exception('Encryption: Unable to get key.');
    			}
    			
    			return base64_decode(file_get_contents($filename));
    		}
    		catch (Exception $exception)
    		{
    			echo $exception->getMessage();
    		}
    	}
    	
    	protected function get_decryption($string)
    	{
    		$decryption = json_decode($string);
    		
    		if (!is_null($decryption))
    		{
    			return $decryption;
    		}
    		
    		return $string;
    	}
    	
    	protected function get_encryption($encryption)
    	{
    		$encryption = substr($encryption, 1, -1);
    		$encryption = explode('>:<', $encryption);
    
    		try 
    		{
    			if (count($encryption) !== 3)
    			{
    				throw new Exception('Encryption: Unknown encryption.');
    			}
    			else if ($encryption[0] < $this->version())
    			{
    				throw new Exception('Encryption: Encrypted data out of date.');
    			}
    			if ($encryption[0] > $this->version())
    			{
    				throw new Exception('Encryption: PHP libsodium extension out od date.');
    			}
    			
    			return array(
    				'nonce' 	 => base64_decode($encryption[1]),
    				'ciphertext' => base64_decode($encryption[2])
    			);
    		}
    		catch (Exception $exception)
    		{
    			echo $exception->getMessage();
    		}
    	}
    }
    
    

    usage

    $text_encryption = new Text_Encryption(PRIVATE_DIRECTORY . 'config/keys');
    $ciphertext = $text_encryption->encrypt(array(test'));
    print_r($text_encryption->decrypt($ciphertext));
    
    $ciphertext2 = $text_encryption->encrypt('test');
    echo $text_encryption->decrypt($ciphertext2);
    

    thanks again

  9. firstly i apologies for such a late reply on the topic as i know guys spend a lot of your time helping out us members.

     

    well i didn't realize i was open to such big attacks when using unserialize() and deserialize()  thanks for the advise.

     

    regarding encyrption at some point i need to encrypt sessions, cookies, passwords and any other sessitive data added to the database, i downloaded libsodium now i'm trying to understand how it is best to use library.

     

    i have found an example just of plain text encrypting and decrypting....would this be a good example?

    <?php
    // This requires the libsodium PECL extension
    
    /**
     * Encrypt a message
     * 
     * @param string $message - message to encrypt
     * @param string $key - encryption key
     * @return string
     */
    function safeEncrypt($message, $key)
    {
        $nonce = \Sodium\randombytes_buf(
            \Sodium\CRYPTO_SECRETBOX_NONCEBYTES
        );
    
        $cipher = base64_encode(
            $nonce.
            \Sodium\crypto_secretbox(
                $message,
                $nonce,
                $key
            )
        );
        \Sodium\memzero($message);
        \Sodium\memzero($key);
        return $cipher;
    }
    
    /**
     * Decrypt a message
     * 
     * @param string $encrypted - message encrypted with safeEncrypt()
     * @param string $key - encryption key
     * @return string
     */
    function safeDecrypt($encrypted, $key)
    {   
        $decoded = base64_decode($encrypted);
        $nonce = mb_substr($decoded, 0, \Sodium\CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
        $ciphertext = mb_substr($decoded, \Sodium\CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    
        $plain = \Sodium\crypto_secretbox_open(
            $ciphertext,
            $nonce,
            $key
        );
        \Sodium\memzero($ciphertext);
        \Sodium\memzero($key);
        return $plain;
    }
    
    

    thank you

  10. hey guys i have some help from jacques a while back regarding aes encryption in php, which works great!...i made the encryption/decryptions compatable with nodejs, but i'd like to know how i can make it compatable with mysql also.

     

    here is what i use to encrypt

    $data                           = 'hello';
    $encryption_algorithm = 'AES-128-CBC';
    $master_key                = 'fba05a681b7606c57d6218d4cca387f5cd4f8e0ae098cb4d9b7e';
    
    $init_vector = openssl_random_pseudo_bytes(openssl_cipher_iv_length($encryption_algorithm));
    $ciphertext  = openssl_encrypt(serialize($data), $encryption_algorithm, $master_key, false, $init_vector);
    

    result:

     

    e4a844130207ad0364c442387d5b9b8e:4d43ca26887385ee94eb27010b8d48fa

     

     

     

     

    i was in work thinking of my project and i plan on encypting everything except for primary key. ie:

    users
    -----------------------
    user_id
    username                (encrypted)
    password                 (encrypted)
    email_address          (encrypted)
    telephone_number    (encrypted)
    -----------------------
    

    now if i decided to select user where username = 'JohnDoe' i'd been doomed as the username is encypted.

     

    i know mysql offers the AES_DECRYPT and AES_ENCRYPT function but i've read its not very safe?

     

    is it possible to find an enrypted row by column value which is compatable to my php script?

     

    any advise/links would be appreciated

     

    thank you

     

     

  11. Thanks one again for the great advice jacques :)

     

    Well im going to scrap the head helper nonsence and create a template engine myself...but still keep the idea of setting an array of header tags so i can call all globals

     

    :)

  12. sorry for the late reply i have been doing some research regarding this xss...i didn't realise a web page could be so vulnerable in so many asspects of xxs.

     

    so every string must be encoded using

    htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
    

    so i need to encode the attributes set in my view helper?...that would imply that the design would xxs?

     

    i'm sorry i don't understand fully how a user browsing can inject code from the following example, unless the $id is changed inside the file...how is it possible to do it via the browser?

    <php
    $id = "test-id"
    ?>
    
    <div id="{$id}">this is a test</div>
    

    but i do understand that with user input such as my forum reply it needs to be encoded to ensure no xss

     

     

    {% for blog_post in blog_posts %}
        <li>{{ blog_post.title }}</li>
    {% else %}
        no entries
    {% endfor %}
    

     

    i'm not going to argue with you jacques, this looks alot easier on the eye :)

     

    thank you for your help

  13. Are you sure you're referencing the same view object in both locations and running the code in the right order?

     

    i found the problem which was so stiupid of me...i hate to say what i did wrong :suicide: sorry!

     

     

    Which frameworks?

     

    well i've never used a framework other than my own...i thought zend framrwork would be good so i read the files and manuel and based mine around that

     

    the helpers are only for the script, link, title and meta i wouldnt create helpers for every html element

     

     i use a decorator like so

    <?php
    
    namespace Head\View;
    
    use Exception\Exception as Exception;
    use HTML\Decorator_Abstract as Decorator_Abstract;
    use HTML\Decorator_Interface as Decorator_Interface;
    
    class Script Extends Decorator_Abstract implements Decorator_Interface
    {
        CONST ATTRIBUTES = array(
            'charset',
            'src',
            'type'
        );
        
        CONST BOOLEAN_ATTRIBUTES = array(
            'async',
            'defer'
        );
        
        CONST ATTRIBUTE_VALUES = array(
            'type' => array(
                'text/javascript', 
                'text/ecmascript', 
                'application/ecmascript', 
                'application/javascript'
            )
        );
        
        protected function opening_tag()
        {
            return sprintf("<script%s>", $this->attributes());
        }
        
        protected function closing_tag()
        {
            return '</script>';
        }
        
        public function render()
        {
            return $this->opening_tag() . $this->closing_tag();
        }
    }

    regarding using a template engine with the view, i don't really see the point :confused:

     

    i'm able to extract variables to the html like so

    $this->view->name = 'Destramic';
    

    and use in my template like so

    $this->name;
    

    wouldn't using a template engine just over-complicate thing? with all the var, if, foreach syntax?

     

    thank for your help

  14. You need to narrow the problem down. Right now, there are way too many classes and methods involved, most of which we don't know and don't need to know. Where is the problem? In Head? Script? Placeholder?

     

    In a properly designed OOP infrastructure, objects can be tested individually. Do that, preferrably with automated unit tests.

     

    good point...ok i did just that

    use MVC\View\View as View;
    
    $view = new View;
    
    $view->head->script(array(
        'src' => 'test4'
    ))->append(array(
        'scr' => 'hi4'
    ));
    
    $view->head->script->append(array(
        'src' => 'test3'
    ))->append(array(
        'scr' => 'hi3'
    ));
    
    echo $view->head->script;
    
    use MVC\View\Helper as Helper;
    
    $helper = new Helper;
    
    $helper->head->script(array(
        'src' => 'test4'
    ))->append(array(
        'scr' => 'hi4'
    ));
    
    $helper->head->script->append(array(
        'src' => 'test3'
    ))->append(array(
        'scr' => 'hi3'
    ));
    
    echo $helper->head->script;
    
    
    use View\Helper\Head as Head;
    
    $head = new Head;
    $head->script(array(
        'src' => 'test2'
    ))->append(array(
        'scr' => 'hi2'
    ));
    
    $head->script->append(array(
        'src' => 'test3'
    ))->append(array(
        'scr' => 'hi3'
    ));
    
    echo $head->script;
    
    use Helper\Head\Script as Script;
    
    $script = new Script;
    
    $script->set(array(
        'src' => 'test'
    ))->append(array(
        'scr' => 'hi'
    ));
    
    echo $script;
    

    which returns :

    // from view
    
    Array
    (
        [0] => Array
            (
                [src] => test4
            )
    
        [1] => Array
            (
                [scr] => hi4
            )
    
        [2] => Array
            (
                [src] => test3
            )
    
        [3] => Array
            (
                [scr] => hi3
            )
    
    )
    
    // from helper
    
    Array
    (
        [0] => Array
            (
                [src] => test4
            )
    
        [1] => Array
            (
                [scr] => hi4
            )
    
        [2] => Array
            (
                [src] => test3
            )
    
        [3] => Array
            (
                [scr] => hi3
            )
    
    )
    
    // from head
    
    Array
    (
        [0] => Array
            (
                [src] => test2
            )
    
        [1] => Array
            (
                [scr] => hi2
            )
    
        [2] => Array
            (
                [src] => test3
            )
    
        [3] => Array
            (
                [scr] => hi3
            )
    
    )
    
    // from script
    
    Array
    (
        [0] => Array
            (
                [src] => test
            )
    
        [1] => Array
            (
                [scr] => hi
            )
    
    )
    
    

    well i didn't expect it all to return results as it did...now i'm scratchig my head a bit here

     

    why when called like so does it return an empty array :confused:

    // controller
    
    $this->view->head->script(array(
               'src' => 'test'
    ));
    
    // view
    
    <?= $this->head->script; ?> 
    
    Your code is also bloated and relies too much on magic. Why on earth does the Head class need 20(!) lines of code to instantiate two classes? And is that all the class does, hold two unnecessarily hard-coded class references which make it impossible to use any other script class?

     

    i want to use it for all head tags doctype, link, title etc...its how i see modern frameworks set thier head and then just call when needed in the view...i just asume that is the correct way as i have no real idea of what is the best practice other than what i see or unless you guys tell me different :)

     

     

    The whole approach seems questionable. You're appearently trying to reinvent HTML in an object-oriented manner, and the only thing which sets you apart is that Destramic-HTML requires 10 times as many lines as plain HTML. Have you considered using an actual template engine like Twig? OOP is great for many tasks, but it's horrible for describing the structure of a document. That's what declarative languages like HTML are for.

     

    i suppose i could just scrap the whole idea altogether and just put html where it needs to go, but i find with this method i could have all control of the head inside my controller....i did notice a post of yours metioning a template engine with thier mcv before, but its maybe something i coiuld look into if that is a good way to go

     

    but with my method i'm able to set all default links, scripts, title etc and just call in my view, with the option of appending inside the controller too.

  15. hey guys i'm currently writing a head helper and probably down to my bad design i'm unable to return array stored in my placeholder

     

    here is my head helper:

    <?php
    
    namespace View\Helper;
    
    use Exception\Exception as Exception;
    
    class Head
    {
        private $_tags = array(
            'script' => 'Helper\Head\Script',
            'link'   => 'Helper\Head\Link'
        );
        
        public function __get($key)
        {
            if (isset($this->_tags[$key]))
            {
                if (is_object($this->_tags[$key]))
                {
                    return $this->_tags[$key];
                }
                else if (class_exists($this->_tags[$key]))
                {
                    $this->_tags[$key] = new $this->_tags[$key];
                    
                    return $this->_tags[$key];
                }
            }
    
            return null;
        }
        
        public function __call($key, $arguments)
        {
            if (!is_null($this->$key))
            {
                $this->$key->set($arguments[0]);
                
                return $this->$key;
            }
            
            return null;
        }
    }
    

    pre set scripts within bootstrap

           $view->head->script(array(
               'src' => 'test'
           ))->prepend(array(
               'src' => 'hello'
           ));
    

    append to the scripts witin controller

           $this->view->head->script->append(array(
               'src' => 'bye'
           ));
    

    script class

    <?php
    
    namespace Helper\Head;
    
    use Exception\Exception as Exception;
    use Placeholder\Placeholder as Placeholder;
    use Head\View\Script as Script;
    
    class Script extends Placeholder
    {
        public function __toString()
        {
            print_r($this->get());
            
           // $script = new Script(array('src' => 'hello'));
           // return $script->render();
           
            return 'return';
        }
    }
    

    when __toString is executed in my view, the array stored in my placeholder is empty.

    <?= $this->head->script; ?> 
    Array()
    

    i know the problem all lies down to the head helper, because when using the __call or __get method it returns the script object which has not reference of previous appends/depends of the script tag.

     

    ummm i hope i explained myself enough :-\ and that there is a simple way of makig this work to how i want.

     

     

    previously i used to something like this but it looks ugly when setting scripts

    public function __call($method, $parameters)
    	{	
    		if (preg_match('/^(?P<action>set|(ap|pre)pend)]*(_)*(?P<type>title|meta|script|link)$/', $method, $matches))
    		{
    			$parameters = $parameters[0];
    			
    			$tag_name = $matches['type'];
    			$action   = $matches['action'];
    			
    			$tag = $this->get_tag($tag_name);	
    			return $tag->$action($parameters);
    		}
    	}
    
    // $this->view->head->set_script()->append();
    
    

    if you require to look at any code please let me know...thank you for your time

  16. it's hard to build a good framework in my opinion...i'm currently re-designing mine which i made 3 years ago....but with mine you have the view, modlel, controller but also the module which i get quite confused at and have yet to understand fully what's used for...that aside as you questions are not too specific and i'd suggest to download a framework such as zend (like i did) and spending time reading the manuel and stripping apart the code to understand the logic and the design of a framework

     

    first of all i have a router class which matches routes to a specific uri, then the controller, action and parameters are dispatched and load the contoller... the controller i'm able to access the view and the model 

     

    i think if your trying to build a mvc, which is good in my optioin, cause i hate to use code i haven't written myself, then you you need to break down what each element does and how it's going to perform, plus cut out all the BS! inbetween.

     

    posting some code would be useful and maybe we could give you some points.

  17. well i've learned something here :happy-04:

     

    had a read and this seems to do the trick on duplicate posts, unless i missed something

    <?php
    session_start();
    
    if (isset($_SESSION['form']))
    {
        print_r($_SESSION);
        print_r($_POST);
        
        // use data
        
        unset($_SESSION['form']);
    }
    else if (isset($_POST['submit'])) 
    {
        $_SESSION['form'] = $_POST;
        header("Location: " . $_SERVER['REQUEST_URI']);
        exit;
    }
    else 
    {
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <title>Demo</title>
    </head>
    <body>
        <h1>The Form</h1>
        <form action="" method="POST">
            Some Data:
            <input type="text" value="some data" name="data" id="data" /><br />
            <input name='submit' type="submit" />
        </form>
    </body>
    </html>
    <?php
    }
    ?>
    
  18. doh!...sorry i read something wrong, you are correct....i just got the manuel up

     

     

    If set to PREG_GREP_INVERT, this function returns the elements of the input array that do not match the given pattern.

     

    a function like this would be great...a loop with preg_match is is then...i'm not sure it's going to save time caching it this way though...time will tell :)

  19. i tried that but even then it returns the same array

     

     

    Array
    (
    [0] => /register
    [1] => /register/(?P
    <activation_code>[^\s]+
    )

     

    i did just realised that  /register/(?P<activation_code>[^\s]+)    didnt have a ) at the end

     

    still the same problem though

    $uri = '#^/register/aqwrgj73ffgsegr2h$#';
    
    $routes = array(
        '/register',
        '/register/(?P<activation_code>[^\s]+)'
    );
    
    $match = preg_grep($uri, $routes, PREG_GREP_INVERT);
    print_r($match);
    
    
  20. hey guys i'm currently trying to create a cache system for my router, which i think i'm always there but i'm having a slight problem with preg_grep()

     

    here is how it goes...the routes are added

    Router::add_route('/register', array());
    Router::add_route('/register/:activation_code', array());
    

    (this is an example - i wouldnt really need to add two routes for /register page)

     

    the routes get added to my router class and then get passed to the route pattern class where the patterns will get phased.

    <?php
    
    namespace Router;
    
    use Exception\Exception as Exception;
    
    class Route_Pattern
    {
        const ROUTE_VARIABLES         = '(?<=\/)(?[ahis])(?=?!.*?\{)))?(?:\w++)(?!\{\w+\}))?(?\*)|\{([\w-]+(?:\|[\w-]+)+)*\})?(?<!\/)';
        const ROUTE_OPTIONAL_SEGMENTS = '(?:^|\G)[^\[\]]*(\[\/((?:[ahis]??[\w-]+)(?:\[\/((?:[ahis]??[\w-]+)\])?\])(?=\[|$)';
        
        private $_character_types = array(
            'i'  => '[\d]++',
            'a'  => '[\dA-Za-z]++',
            'h'  => '[\dA-Fa-f]++',
            's'  => '[\w-]++',
        );
        
        private $_route_pattern;
        
        public function phase($route_pattern)
        {
            if (is_null($route_pattern))
            {
                throw new Exception('Route Pattern: Route pattern is empty.');
            }
            
            $this->_route_pattern = $route_pattern;
            
            $this->optional_segments();
            $this->variables();
           
            return $this->_route_pattern;
        }
        
        private function variables()
        {
            $parameters = $this->match(self::ROUTE_VARIABLES, $this->_route_pattern);
         
            if ($parameters)
            {
                $count = count($parameters[0]);
        
                for ($i = 0; $i < $count; $i++)
                {
                    $match          = $parameters[0][$i];
                    $character_type = $parameters[1][$i];
                    $parameter      = $parameters[2][$i];
                    $all_variable   = $parameters[3][$i];
                    $static_values  = $parameters[4][$i];
                    
                    if ($static_values)
                    {
                        $replace = '(' . $static_values . ')';
                    }
                    else
                    {
                        $replace = $this->character_type($character_type);
                    }
                    
                    if ($parameter)
                    {
                        $replace = '(?P<' . $parameter . '>'. $replace . '+)';
                    }
    
                    $this->_route_pattern = $this->replace($match, $replace, $this->_route_pattern);
                }
            }
    
            return $this->_route_pattern;
        }
    
        private function optional_segments()
        {
            $parameters = $this->match(self::ROUTE_OPTIONAL_SEGMENTS, $this->_route_pattern);
    
            if ($parameters)
            {
                $count = count($parameters[0]);
            
                for ($i = 0; $i < $count; $i++)
                {
                    $match    = $parameters[1][$i];
                    $segment1 = $parameters[2][$i];
                    $segment2 = $parameters[3][$i];
                   
                    $replace = '(/' . $segment1;
                    
                    if ($segment2)
                    {
                        $replace .= '/' . $segment2;
                    }
                    
                    $replace .= ')?';
                        
                    $this->_route_pattern = $this->replace($match, $replace, $this->_route_pattern);
                }
            }
            
            return $this->_route_pattern;
        }
    
        private function character_type($character_type = null)
        {
            if (isset($this->_character_types[$character_type]))
            {
                return '(' . $this->_character_types[$character_type] . ')';
            }
    
            return '[^\s]';
        }
    
        private function replace($search, $replace, $subject)
        {
            $search = '#' . preg_quote($search) . '#';
            
            return preg_replace($search, $replace, $subject, 1);
        }
        
        private function match($pattern, $subject)
        {
            $pattern = '#' . $pattern .'#';
        
            if (preg_match_all($pattern, $subject, $matches))
            {
                return $matches;
            }
             
            return false;
        }
    }
    

    uri:                                          /register/aqwrgj73ffgsegr2h   

    route pattern                          /register/:activation_code

    route pattern phased:           /register/(?P<activation_code>[^\s]+

     

    so i decided i'd cache the phased route pattern and use preg_grep (which i'm new to) to match the uri to a single pattern.

     

    now here is the problem at hand

    $uri = '/register/aqwrgj73ffgsegr2h';
    
    $routes = array(
        '/register',
        '/register/(?P<activation_code>[^\s]+'
    );
    
    $match = preg_grep($uri, $routes, PREG_GREP_INVERT);
    
    print_r($match);
    

    which returns

    Array
    (
        [0] => /register
        [1] => /register/(?P<activation_code>[^\s]+
    )
    

    so my question is why is key 0 (/register) present? as its not even a match

     

    what i'd expect to have matched is /register/(?P<activation_code>[^\s]+

     

    any help on this or my methods would be greatly appreciated...thanks guys

  21. i only gone and nailed it :)

    #/([ahis])?(\w+))?(?\(([\w-+]+(?:\|[\w-]+)+)*\))|(\*)|(?<=:\w))(?![^\[\]]*\])#
    

    There are too many things that are optional in that regex. Either you need to make some stuff required or you should combine some of them with alternation and make the whole set required.

    (first?)(second?)(third?) -> (?:first|second|third)
    If neither of those then we might have to rebuild the regex from scratch...

     

     

    thanks you for pointing me into the right direction requinix

×
×
  • Create New...

Important Information

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.