codeigniter url encrypt not working - php

<a href="<?php echo base_url().'daily_report/index/'.$this->encrypt->encode($this->session->userdata('employee_id')) ?>">
i have encrypted the above url using the codeigniter encrypt
i set the encryption key in codeigniter config file
$config['encryption_key'] = 'gIoueTFDwGzbL2Bje9Bx5B0rlsD0gKDV';
and i called in the autoload
$autoload['libraries'] = array('session','form_validation','encrypt','encryption','database');
when the ulr(href) load into the url it look like this
http://localhost/hrms/daily_report/index/FVjGcz4qQztqAk0jaomJiAFBZ/vKVSBug1iGPQeKQCZ/K7+WUE4E/M9u1EjWh3uKTKeIhExjGKK1dJ2awL0+zQ==
but the url is not decoded, and i;m not getting the employee_id it shows empty.
public function index($employee_id) {
$save_employee_id = $employee_id;
// decoding the encrypted employee id
$get_employee_id = $this->encrypt->decode($save_employee_id);
echo $employee_id; // answer: FVjGcz4qQztqAk0jaomJiAFBZ
echo "<br>";
echo $get_employee_id; // is display the null
echo "<br>";
exit();
// get the employee daily report
$data['get_ind_report'] = $this->daily_report_model->get_ind_report($get_employee_id);
// daily report page
$data['header'] = "Daily Report";
$data['sub_header'] = "All";
$data['main_content'] = "daily_report/list";
$this->load->view('employeelayout/main',$data);
}
complete url(3) is
FVjGcz4qQztqAk0jaomJiAFBZ/vKVSBug1iGPQeKQCZ/K7+WUE4E/M9u1EjWh3uKTKeIhExjGKK1dJ2awL0+zQ==
it shows only
FVjGcz4qQztqAk0jaomJiAFBZ
i tried to change in the
$config['permitted_uri_chars'] = 'a-zA-Z 0-9~%.:_\-#=+';
by / in the permitted uri chars
but it throwing error
So, i need to encryption the $id in the url using the codeigniter encrypt class and decrypt in the server side to get the actual $id, So that i fetch data from the DB. any help would be appreciated

You have to extend encryption class and avoid the / to get it working. Place this class in your application/libraries folder. and name it as MY_Encrypt.php.
class MY_Encrypt extends CI_Encrypt
{
/**
* Encodes a string.
*
* #param string $string The string to encrypt.
* #param string $key[optional] The key to encrypt with.
* #param bool $url_safe[optional] Specifies whether or not the
* returned string should be url-safe.
* #return string
*/
function encode($string, $key="", $url_safe=TRUE)
{
$ret = parent::encode($string, $key);
if ($url_safe)
{
$ret = strtr(
$ret,
array(
'+' => '.',
'=' => '-',
'/' => '~'
)
);
}
return $ret;
}
/**
* Decodes the given string.
*
* #access public
* #param string $string The encrypted string to decrypt.
* #param string $key[optional] The key to use for decryption.
* #return string
*/
function decode($string, $key="")
{
$string = strtr(
$string,
array(
'.' => '+',
'-' => '=',
'~' => '/'
)
);
return parent::decode($string, $key);
}
}

FVjGcz4qQztqAk0jaomJiAFBZ/vKVSBug1iGPQeKQCZ/K7+WUE4E/M9u1EjWh3uKTKeIhExjGKK1dJ2awL0+zQ==
Shows
FVjGcz4qQztqAk0jaomJiAFBZ
If you look at your url closely, you could see that after the result which has been shown there is a '/' . Now any string after that will be treated as another segment. Hence it could not decode.
The encrypt library in this case would not work.
Either you stop passing that through the URL or use another different technique base_encode().
Hope that helps

This is happening as the character "/" is part of html uri delimiter. Instead you can work around it by avoiding that character in html url by rawurlencoding your encrytion output string before attaching it to url.
\edit:
I tried rawurlencode, but wasn't able to get the proper output.
Finally succeeded by using this code.
Define two functions:
function hex2str( $hex ) {
return pack('H*', $hex);
}
function str2hex( $str ) {
return array_shift( unpack('H*', $str) );
}
Then use call str2hex and pass it the encrypted user id to convert encrypted string into hexcode.
Reverse the process to get the correct string so that you can decrypt it.
I was able to properly encode and decode:
"FVjGcz4qQztqAk0jaomJiAFBZ/vKVSBug1iGPQeKQCZ/K7+WUE4E/M9u1EjWh3uKTKeIhExjGKK1dJ2awL0+zQ=="
to:
"46566a47637a3471517a7471416b306a616f6d4a694146425a2f764b56534275673169475051654b51435a2f4b372b57554534452f4d397531456a576833754b544b65496845786a474b4b31644a3261774c302b7a513d3d"
The url would become rather long though.

Related

PHP AES encryption key

I have a PHP and MySQL system and I need to encrypt user data with AES-256. I know how to encrypt and decrypt the data using AES-encrypt/decrypt but I'm not sure how to securely store the AES encryption key. Would it be recommended to store the key inside of a file outside of the public website folder, then use
<?php include('')?>
to call the key for the encryption?
Thanks
Access to your data should currently be constrained by a username/password for MySQL - Where do you store that?
Adding encryption into the mix raises the possibility of splitting the things-you-need-to-know-to-access-the-data across different substrates - with different exposures.
The link in the comment by Mehdi covers some of the options at a fairly abstract level. It doesn't mention, for example, storing the key at the client. But the choice of which method(s) you use depends on the infrastructure, code management, deployment and operational processes in place. The right choice for a low end shared web-hosting service is not the right choice for a dedicated datacentre and vice versa.
You do propose a specific method for managing the key: storing it outside the document root limits access. If you go further and store it in something which is recognized as PHP code by your webserver then access via the webserver should only expose the output of the PHP code - conversely if it were stored in a text file, and someone could get the webserver to serve the file, they would have access to the key.
OTOH its not a great solution if the key hows up in your github repository, or if other people have access to your filesystem/backups/logs.
You need to think about about how you develop code, whom should be able to use the key, whom should be able to see the key itself, whom should definitely not be able to see the key, how your backups are managed, whom has access to your storage.....
It is impossible to provide sufficient information in a question here on SO to get an informed and definitive answer.
At the bottom of the above answer,
I've added:
/*
$key will store in the database in refrence of this content and this key will use to decrypt the data as given below
$
*/
$content = 'blahlol';
$aes = new AES_Encrypt();
$encryptedData = $aes->setData($content)->encrypt()->getEncryptedString();
$key = $aes->getKey();
echo $encryptedData;
echo '<br>';
$decryptedData = $aes->setData($encryptedData)->decrypt()->getDecryptedString();
echo $decryptedData;
//The code above outputs an encrypted string followed by "blahlol" which is my $content variable.
//Below, I'm trying to grab the encrypted string from the database and decrypt it. However it outputs nothing
echo '<br><br><br><br>Database:<br><br>';
$sql = "SELECT * from data WHERE id = '1'";
$result = $con->query($sql);
while($rowLol = $result->fetch_assoc()) {
echo $rowLol['data']; //Outputs encrypted string
$aes = new AES_Encrypt($key);
$decryptedData = $aes->setData($rowLol['data'])->decrypt()->getDecryptedString();
echo $decryptedData; //Meant to output decrypted string (blahlol)
}
?>
At the top, it outputs the encrypted string of "blahlol" followed by plaintext "blahlol" after decryption. However I'm trying to decrypt it by getting the encrypted string for the database.
As noted in the code, the decrypted part outputs nothing.
There are two way you can keep encrypted data.
File
Databse
If data is less you can manage encrypted data in the database and if data is large then it is good to store encrypted data in file outside the public folder.
To make data more secure, use unique key to encrypt every data and save that unique key in the database including data reference value, so when you will decrypt data using referred unique key from the database.
Create php class to handle this.
<?php
class AES_Encrypt {
/**
* #var string
*/
private $key;
/**
*
* #var String
*/
private $string;
/**
*
* #var String
*/
private $encryptedString;
/**
*
* #var String
*/
private $decryptedString;
/**
* Constructor
*/
public function __construct($key = null) {
if (empty($key)) {
$this->setKey(md5($this->randomStr(5)) . '.' . base64_encode(openssl_random_pseudo_bytes(32)));
} else {
$this->setKey($key);
}
}
/**
*
* #param String $key
* #return \AES_Encrypt
*/
public function setKey($key) {
$this->key = $key;
return $this;
}
/**
* Return security key
* #return string
*/
public function getKey() {
return $this->key;
}
/**
*
* #param type $string
* #return \AES_Encrypt
*/
public function setData($string) {
$this->string = $string;
return $this;
}
/**
*
* #return string
*/
public function getData() {
return $this->string;
}
/**
* Convert encrypt string from plain
* #return \AES_Encrypt
*/
public function encrypt() {
$privateKey = explode('.', $this->getKey(), 2);
// Remove the base64 encoding from our key
$encryption_key = base64_decode($privateKey[1]);
// Generate an initialization vector
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
// Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
$encrypted = openssl_encrypt($this->getData(), 'aes-256-cbc', $encryption_key, 0, $iv);
// The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
$this->encryptedString = base64_encode($encrypted . '::' . $iv);
return $this;
}
/**
*
* #return string
*/
public function getEncryptedString() {
return $this->encryptedString;
}
/**
*
* #return string
*/
public function getDecryptedString() {
return $this->decryptedString;
}
/**
* Convert decrypt string
*/
public function decrypt() {
$privateKey = explode('.', $this->getKey(), 2);
// Remove the base64 encoding from our key
$encryption_key = base64_decode($privateKey[1]);
// To decrypt, split the encrypted data from our IV - our unique separator used was "::"
list($encrypted_data, $iv) = explode('::', base64_decode($this->getData()), 2);
$this->decryptedString = openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv);
return $this;
}
/**
*
* #param type $length
* #return string
*/
public function randomStr($length = 5) {
$string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$charactersLength = strlen($string);
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= $string[rand(0, $charactersLength - 1)];
}
return $str;
}
}
$aes = new AES_Encrypt();
$encryptedData = $aes->setData($content)->encrypt()->getEncryptedString();
$key = $aes->getKey();
/*
$key will store in the databse in refrence of this content and this key will use to decrypt the data as given below
*/
$aes = new AES_Encrypt($key);
$decryptedData = $aes->setData($encryptedContent)->decrypt()->getDecryptedString();

Codeigniter encryption without slash

I know this may look like duplicate from this question: Ignore slash while using encryption in Codeigniter. But I still didn't have the answer from it.
I want to sent encrypted email name as URL to their email account.
Then that URL is decrypted to search if that email name is exist in my database to permit that email into my system.
The problem is:
If I use urlencode or base64_encode after encryption, it always resulted in empty value to search the database after decrypt. I think it because the encrypted value always changing.
If I use the casual encryption, it might have the ("/") character.
If I only use the encode, without the encryption, it might permit the email name to have access into my system.
Lastly, I found some library: Ignore Slash while using encryption in codeigniter - GitHub .
But it gave me this error: Undefined property: CI_Loader::$my_encrypt
I don't know what I've done wrong, I already:
Capitalized the class name first letter.
Using the same file name with the class name. (capitalized too)
Change the extend to CI_Encryption because the Encrypt class is already deprecated.
Insert the public function __construct() {parent::__construct();} before all method.
Place the file inside application/library.
Load the library $this->load->library('my_encrypt');
Load the method using $this->my_encrypt->encode($key); this is the line that gave me an error.
I know that this may sound like a simple mistake, but I'm using another third-party library too but it didn't give me an error at all.
Can anyone help me find the mistake / missing step there?
Update -
Before I load the library in the controller, I want to check the result first in view. But it doesn't give me any changes even when I put the code inside controller. Here is the code :
$key = 'example#gmail.com';
$this->load->library('my_encrypt');
$segment = $this->my_encrypt->encode($key);
echo $segment;
echo ( $this->my_encrypt->decode($segment) );
Update:
Fix library code to extend with CI_Encryption library
Have you loaded the library? Name librabry as MY_Encrypt.php in application libraries
<?php
class MY_Encrypt extends CI_Encrypt
{
/**
* Encodes a string.
*
* #param string $string The string to encrypt.
* #param string $key[optional] The key to encrypt with.
* #param bool $url_safe[optional] Specifies whether or not the
* returned string should be url-safe.
* #return string
*/
public function __construct() {
parent::__construct();
}
function encode($string, $key="", $url_safe=TRUE)
{
$ret = parent::encode($string, $key);
if ($url_safe)
{
$ret = strtr(
$ret,
array(
'+' => '.',
'=' => '-',
'/' => '~'
)
);
}
return $ret;
}
/**
* Decodes the given string.
*
* #access public
* #param string $string The encrypted string to decrypt.
* #param string $key[optional] The key to use for decryption.
* #return string
*/
function decode($string, $key="")
{
$string = strtr(
$string,
array(
'.' => '+',
'-' => '=',
'~' => '/'
)
);
return parent::decode($string, $key);
}
}
?>
Now call the encrypt library and use the encryption class instead of my_encrypt
$key='Welcome';
$this->load->library('encrypt');
$key1= $this->encrypt->encode($key);
echo $key1;
fixed to extend the CI_Encryption library, sorry for bothering. :)
class MY_Encrypt extends CI_Encryption
{
/**
* Encodes a string.
*
* #param string $string The string to encrypt.
* #param string $key[optional] The key to encrypt with.
* #param bool $url_safe[optional] Specifies whether or not the
* returned string should be url-safe.
* #return string
*/
public function __construct() {
parent::__construct();
}
function encode($string)
{
$ret = parent::encrypt($string);
if ( !empty($string) )
{
$ret = strtr(
$ret,
array(
'+' => '.',
'=' => '-',
'/' => '~'
)
);
}
return $ret;
}
/**
* Decodes the given string.
*
* #access public
* #param string $string The encrypted string to decrypt.
* #param string $key[optional] The key to use for decryption.
* #return string
*/
function decode($string)
{
$string = strtr(
$string,
array(
'.' => '+',
'-' => '=',
'~' => '/'
)
);
return parent::decrypt($string);
}
}
?>

Get filename with extension from url on log string using PHP PCRE regex

I'm writing a script for parsing a log file from an network device. The log file generated from the device it's not regular, the lines doesn't follow a logic sequence and haves multiple patterns. My script needs to extract from the log lines only the ones that matches an specific pattern and from that lines specific information as datetime, entry type, resource type and resource name from the url in the string. The pattern that I need to match it's the following:
dd-mm-yyyy hh:mm:ss INFO spx.resource.media - New Resource 'URI' [flags] (dlc/tcd)
where 'INFO' is the entry type, 'spx.resource.media' the resource type and in the URI resides the resource name. Currently we need to filter those that haves a specifics extensions.
I reviewed several posts that cover this subject and using this online tool: I came with this regular expresion:
/(\d{2}-\d{2}-\d{4}\s{1}\d{2}:\d{2}:\d{2})\s{1,}(\w{4})\s{1,}(spx.resource.media)(.{1,}(?<=(?:.jpg)|(?:.png)))/g
The problem is that the last regex group matches the whole URI plus the characters and spaces from the resource type and on, and y only need the filename with the extension. I tried this 'regex-to-get-a-filename-from-a-url' (can't post the link insufficient reputation) but doesn't workout 'cause the debugger marks the ^/ as unescaped delimiter. Also if removed doesn't work. A portion of the log can be found here. I really need to get this.
Thanks for reading and/or answering
have a look at this. First Identify the location of the file then you can loop through accordingly to get what you want
<?php
$handle = #fopen("/tmp/inputfile.txt", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
echo $buffer;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
?>
A month ago a came with a solution. What I wanted was to extract the filename and the rest of the subgroups with one pattern, I donĀ“t know if this is possible but with my current regex skills is not. So what I did was to use three regex patterns as you can see in the code below:
This code is part of a class that I (obviously) called Parser. First I define the patterns as constants in the class.
/**
* #const string Log line pattern
*/
const LINE_REGEX_PATTERN = '/(\d{2}-\d{2}-\d{4}\s{1}\d{2}:\d{2}:\d{2})\s{1,}(\w{4})\s{1,}(spx.resource.media)(.{1,}(?<=%extensions%))/';
/**
* #const string Full URL pattern
*/
const FULL_URL_PATTERN = '/\b((?:https?|ftps?|file|spx):\/\/[-A-Z0-9+&##\/%?=~_|$!:,.;]*[A-Z0-9+&##\/%=~_|$])/i';
/**
* #const string Filename pattern
*/
const RESOURCE_REGEX_PATTERN = '/((?:[^\/][\d\w\.-]+)(?<=%extensions%))/';
As you can see, I use a placeholder for the file extensions because in this case I need them to be dynamically set by configuration or database query. Next I validate each extracted line against the first pattern
/**
* Line extract
*
* #param string $file_line File line string
*
* #return array An array if matches
* Array (
* [0] => Matched line
* [1] => Date\Time subgroup (format >> d-M-y H:i:s)
* [2] => String flag subgroup
* [3] => Resource type subgroup (not used)
* [4] => Text string containing resource URL
* )
* , null otherwise
*
* #throws RegexException If malformed pattern
*/
private function extractMatches($file_line)
{
$extensions = array();
// build valid extensions subgroup
foreach ($this->valid_extensions as $extension) {
$extensions[] = sprintf("(?:\.%s)", $extension);
}
$matches = array();
// replace extensions placeholder
$pattern = str_replace('%extensions%', implode('|', $extensions), self::LINE_REGEX_PATTERN);
$is_valid = preg_match($pattern, $file_line, $matches);
if ($is_valid === false) {
throw new RegexException();
}
return $matches;
}
From the resulting array (if any) I fetch the 5th element (the one that stores the text with the URL in it), then I passed to two other functions, the first one to full URL extraction and the second one to finally extract the filename. See below:
/**
* Full URL extract
*
* #param string $text Text with URL in it
*
* #return string The URL, empty string otherwise
*
* #throws RegexException If malformed pattern
*/
private function extractUrl($text)
{
$match = array();
$is_valid = preg_match(self::FULL_URL_PATTERN, $text, $match);
if ($is_valid === false) {
throw new RegexException();
} elseif ($is_valid === 1) {
return $match[0];
}
return ''; // No URL found!
}
/**
* Filename extract
*
* #param string $url Resource URL (expects no GET parameters)
*
* #return string Resource filename (includes extension), empty string otherwise
*
* #throws RegexException If malformed pattern
*/
private function extractResourceNameFromUrl($url)
{
$extensions = array();
// build valid extensions subgroup
foreach ($this->valid_extensions as $extension) {
$extensions[] = sprintf("(?:\.%s)", $extension);
}
$matches = array();
// replace extensions placeholder
$pattern = str_replace('%extensions%', implode('|', $extensions), self::RESOURCE_REGEX_PATTERN);
$is_valid = preg_match($pattern, $url, $matches);
if ($is_valid === false) {
throw new RegexException();
} elseif ($is_valid === 1) {
return $matches[1];
}
return '';
}
Finally some where in my app I just did:
$parser = new Parser();
// fetch file line loop
$matches = $parser->extractMatches($file_line);
$url = $parser->extractUrl($matches[4]);
$filename = $parser->extractResourceNameFromUrl($matches[4]);
Hope helps somebody. Thanks!

Advice for implementing simple regex (for bbcode/geshi parsing)

I had made a personal note software in PHP so I can store and organize my notes and wished for a nice simple format to write them in.
I had done it in Markdown but found it was a little confusing and there was no simple syntax highlighting, so I did bbcode before and wished to implement that.
Now for GeSHi which I really wish to implement (the syntax highlighter), it requires the most simple code like this:
$geshi = new GeSHi($sourcecode, $language);
$geshi->parse_code();
Now this is the easy part , but what I wish to do is allow my bbcode to call it.
My current regular expression to match a made up [syntax=cpp][/syntax] bbcode is the following:
preg_replace('#\[syntax=(.*?)\](.*?)\[/syntax\]#si' , 'geshi(\\2,\\1)????', text);
You will notice I capture the language and the content, how on earth would I connect it to the GeSHi code?
preg_replace seems to just be able to replace it with a string not an 'expression', I am not sure how to use those two lines of code for GeSHi up there with the captured data..
I really am excited about this project and wish to overcome this.
I wrote this class a while back, the reason for the class was to allow easy customization / parsing. Maybe a little overkill, but works well and I needed it overkill for my application. The usage is pretty simple:
$geshiH = new Geshi_Helper();
$text = $geshiH->geshi($text); // this assumes that the text should be parsed (ie inline syntaxes)
---- OR ----
$geshiH = new Geshi_Helper();
$text = $geshiH->geshi($text, $lang); // assumes that you have the language, good for a snippets deal
I had to do some chopping from other custom items I had, but pending no syntax errors from the chopping it should work. Feel free to use it.
<?php
require_once 'Geshi/geshi.php';
class Geshi_Helper
{
/**
* #var array Array of matches from the code block.
*/
private $_codeMatches = array();
private $_token = "";
private $_count = 1;
public function __construct()
{
/* Generate a unique hash token for replacement) */
$this->_token = md5(time() . rand(9999,9999999));
}
/**
* Performs syntax highlights using geshi library to the content.
*
* #param string $content - The context to parse
* #return string Syntax Highlighted content
*/
public function geshi($content, $lang=null)
{
if (!is_null($lang)) {
/* Given the returned results 0 is not set, adding the "" should make this compatible */
$content = $this->_highlightSyntax(array("", strtolower($lang), $content));
}else {
/* Need to replace this prior to the code replace for nobbc */
$content = preg_replace('~\[nobbc\](.+?)\[/nobbc\]~ie', '\'[nobbc]\' . strtr(\'$1\', array(\'[\' => \'[\', \']\' => \']\', \':\' => \':\', \'#\' => \'#\')) . \'[/nobbc]\'', $content);
/* For multiple content we have to handle the br's, hence the replacement filters */
$content = $this->_preFilter($content);
/* Reverse the nobbc markup */
$content = preg_replace('~\[nobbc\](.+?)\[/nobbc\]~ie', 'strtr(\'$1\', array(\'&#91;\' => \'[\', \'&#93;\' => \']\', \'&#58;\' => \':\', \'&#64;\' => \'#\'))', $content);
$content = $this->_postFilter($content);
}
return $content;
}
/**
* Performs syntax highlights using geshi library to the content.
* If it is unknown the number of blocks, use highlightContent
* instead.
*
* #param string $content - The code block to parse
* #param string $language - The language to highlight with
* #return string Syntax Highlighted content
* #todo Add any extra / customization styling here.
*/
private function _highlightSyntax($contentArray)
{
$codeCount = $contentArray[1];
/* If the count is 2 we are working with the filter */
if (count($contentArray) == 2) {
$contentArray = $this->_codeMatches[$contentArray[1]];
}
/* for default [syntax] */
if ($contentArray[1] == "")
$contentArray[1] = "php";
/* Grab the language */
$language = (isset($contentArray[1]))?$contentArray[1]:'text';
/* Remove leading spaces to avoid problems */
$content = ltrim($contentArray[2]);
/* Parse the code to be highlighted */
$geshi = new GeSHi($content, strtolower($language));
return $geshi->parse_code();
}
/**
* Substitute the code blocks for formatting to be done without
* messing up the code.
*
* #param array $match - Referenced array of items to substitute
* #return string Substituted content
*/
private function _substitute(&$match)
{
$index = sprintf("%02d", $this->_count++);
$this->_codeMatches[$index] = $match;
return "----" . $this->_token . $index . "----";
}
/**
* Removes the code from the rest of the content to apply other filters.
*
* #param string $content - The content to filter out the code lines
* #return string Content with code removed.
*/
private function _preFilter($content)
{
return preg_replace_callback("#\s*\[syntax=(.*?)\](.*?)\[/syntax\]\s*#siU", array($this, "_substitute"), $content);
}
/**
* Replaces the code after the filters have been ran.
*
* #param string $content - The content to replace the code lines
* #return string Content with code re-applied.
*/
private function _postFilter($content)
{
/* using dashes to prevent the old filtered tag being escaped */
return preg_replace_callback("/----\s*" . $this->_token . "(\d{2})\s*----/si", array($this, "_highlightSyntax"), $content);
}
}
?>
It looks to me like you already got the regex right. Your problem lies in the invocation, so I suggest making a wrapper function:
function geshi($src, $l) {
$geshi = new GeSHi($sourcecode, $language);
$geshi->parse_code();
return $geshi->how_do_I_get_the_results();
}
Now this would normally suffice, but the source code is likely to contain single or dobule quotes itself. Therefore you cannot write preg_replace(".../e", "geshi('$2','$1')", ...) as you would need. (Note that '$1' and '$2' need quotes because preg_replace just substitutes the $1,$2 placeholders, but this needs to be valid php inline code).
That's why you need to use preg_replace_callback to avoid escaping issues in the /e exec replacement code.
So for example:
preg_replace_callback('#\[syntax=(.*?)\](.*?)\[/syntax\]#si' , 'geshi_replace', $text);
And I'd make a second wrapper, but you can combine it with the original code:
function geshi_replace($uu) {
return geshi($uu[2], $uu[1]);
}
Use preg_match:
$match = preg_match('#\[syntax=(.*?)\](.*?)\[/syntax\]#si', $text);
$geshi = new GeSHi($match[2], $match[1]);

How to save encrypted data in cookie (using php)?

I would like to save data in cookies (user name, email address, etc...) but I don't the user to easily read it or modify it. I need to be able able to read the data back. How can I do that with php 5.2+?
It would be used for "welcome back bob" kind of feature. It is not a replacement for persistence or session storage.
We use mcrypt in our projects to achieve encryption. Below is a code sample based on content found on the internet:
<?php
class MyProjCrypt {
private $td;
private $iv;
private $ks;
private $salt;
private $encStr;
private $decStr;
/**
* The constructor initializes the cryptography library
* #param $salt string The encryption key
* #return void
*/
function __construct($salt) {
$this->td = mcrypt_module_open('rijndael-256', '', 'ofb', ''); // algorithm
$this->ks = mcrypt_enc_get_key_size($this->td); // key size needed for the algorithm
$this->salt = substr(md5($salt), 0, $this->ks);
}
/**
* Generates a hex string of $src
* #param $src string String to be encrypted
* #return void
*/
function encrypt($src) {
srand(( double) microtime() * 1000000); //for sake of MCRYPT_RAND
$this->iv = mcrypt_create_iv($this->ks, MCRYPT_RAND);
mcrypt_generic_init($this->td, $this->salt, $this->iv);
$tmpStr = mcrypt_generic($this->td, $src);
mcrypt_generic_deinit($this->td);
mcrypt_module_close($this->td);
//convert the encrypted binary string to hex
//$this->iv is needed to decrypt the string later. It has a fixed length and can easily
//be seperated out from the encrypted String
$this->encStr = bin2hex($this->iv.$tmpStr);
}
/**
* Decrypts a hex string
* #param $src string String to be decrypted
* #return void
*/
function decrypt($src) {
//convert the hex string to binary
$corrected = preg_replace("[^0-9a-fA-F]", "", $src);
$binenc = pack("H".strlen($corrected), $corrected);
//retrieve the iv from the encrypted string
$this->iv = substr($binenc, 0, $this->ks);
//retrieve the encrypted string alone(minus iv)
$binstr = substr($binenc, $this->ks);
/* Initialize encryption module for decryption */
mcrypt_generic_init($this->td, $this->salt, $this->iv);
/* Decrypt encrypted string */
$decrypted = mdecrypt_generic($this->td, $binstr);
/* Terminate decryption handle and close module */
mcrypt_generic_deinit($this->td);
mcrypt_module_close($this->td);
$this->decStr = trim($decrypted);
}
}
I suggest you not only encrypt but also sign the data. If you don't sign the data, you won't be able to tell reliably whether the user modified the data. Also, to avoid replay you may want to add some timestamp/validity period information into the data.
If you don't want your users to read it don't put it in a cookie;
In stead use Session's with a cookie that stays for a longer time. This way the data stays on the server and not at the computer of the user.
See this article about persistant sessions
For encryption example see "symmetric encryption" section in http://www.osix.net/modules/article/?id=606.
To prevent unauthorized modification, use HMAC: http://php.net/hash-hmac, and about hmac in general: http://en.wikipedia.org/wiki/HMAC, http://en.wikipedia.org/wiki/Message_authentication_code
And if you don't have to, don't store sensitive data in a cookie, even encrypted. You may want to read more about "data indirection".
If you absolutely must do this then you can use the symmetric encryption functionality in mcrypt.
http://php.net/mcrypt

Categories