This topic is locked

encrypting fields using phprunner 5.1

5/22/2009 9:00:25 AM
PHPRunner General questions
W
wfcentral author

I tried doing a search for encrypting fields using phpRunner and a lot of the topics are very old from many versions back. Can anyone point me in the right direction.
I need to create a database with about 6 fields. All 6 fields are sensitive information and need to be encrypted. I will create a login so only authorized people can get in and add data. Once they log in, they can add records and then leave. A super-user will be able to login and download the entire list of records to print out.
If the database were to be compromised I would want the data in the fields encrypted so it is useless to the hacker.

Sergey Kornilov admin 5/25/2009

You need to encrypt fields before sending data to the database. Use BeforeAdd/BeforeEdit events for this purpose.
To decrypt data you can use 'View as' type 'Custom'.

S
salus1DevClub member 8/4/2009

Hi,

Any chance of getting an example of the code required to perform this?

Thanks!

X
xliner 8/4/2009

Simple two PHP code snippets (encryption/decryption), turning things by means of ASCII character code + a NUMBER (in this case 2, changeable to whatsoever higher one):
function _enc($s)

{

for( $i = 0; $i < strlen($s); $i++ )

$r[] = ord($s[$i]) + 2;

return implode('.', $r);

}
function _dec($s)

{

$s = explode(".", $s);

for( $i = 0; $i < count($s); $i++ )

$s[$i] = chr($s[$i] - 2);

return implode('', $s);

}

S
salus1DevClub member 8/4/2009

Thanks for taking the time to produce this example. Unfortunately the application will be storing social security numbers and credit card account numbers so I need something more industrial strength. Can anyone supply an example of encrypting / decrypting PHPRunner data fields using MCRYPT functions?

Thanks!

X
xliner 8/4/2009

Thanks for taking the time to produce this example. Unfortunately the application will be storing social security numbers and credit card account numbers so I need something more industrial strength. Can anyone supply an example of encrypting / decrypting PHPRunner data fields using MCRYPT functions?

Thanks!


$key="My Key";

$text="My plain text";
// Encrypt

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);

// Decrypt

$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Salus1:

Key: $key
Text: $text
Encrypt: $crypttext<bR>Decrypt: $decrypttext";

S
salus1DevClub member 8/4/2009

Outstanding, many thanks!

X
xliner 8/4/2009

Outstanding, many thanks!


Other option:

  1. function salus1( $data, $key, $encrypt=true ) {

  2. Serialize, if encrypting


  3. if ( $encrypt ) $data = serialize($data);

  4. Open cipher module


  5. if ( ! $td = mcrypt_module_open('rijndael-256', '', 'cfb', '') )
  6. return false;

  7. $ks = mcrypt_enc_get_key_size($td); # Required key size
  8. $key = substr(sha1($key), 0, $ks); # Harden / adjust length
  9. $ivs = mcrypt_enc_get_iv_size($td); # IV size

  10. $iv = $encrypt ?
  11. mcrypt_create_iv($ivs, MCRYPT_RAND) : # Create IV, if encrypting
  12. substr($data, 0, $ivs); # Extract IV, if decrypting

  13. Extract data, if decrypting


  14. if ( ! $encrypt ) $data = substr($data, $ivs);

  15. if ( mcrypt_generic_init($td, $key, $iv) !== 0 ) # Initialize buffers
  16. return false;

  17. $data = $encrypt ?
  18. mcrypt_generic($td, $data) : # Perform encryption
  19. mdecrypt_generic($td, $data); # Perform decryption

  20. if ( $encrypt ) $data = $iv . $data; # Prepend IV, if encrypting

  21. mcrypt_generic_deinit($td); # Clear buffers
  22. mcrypt_module_close($td); # Close cipher module

  23. Unserialize, if decrypting


  24. if ( ! $encrypt ) $data= unserialize($data);

  25. return $data;

    37.}
    Usage sample:
    1.$privateKey = "This is the private key.";

    2.$secretData = "This is the secret message.";


  26. 4.# Encrypt the secret data

    5.$encryptedData = salus1($secretData, $privateKey);


  27. 7.# Decrypt the ciphertext

    8.$decryptedData = salus1($encryptedData, $privateKey, false);

S
salus1DevClub member 8/4/2009

Thanks for the additional info, think I'd like to stick to the second method, though.

Using this approach I would create a BeforeAdd event which looked like;
$key="SecretKey";

$text=$values["SocialSecurityNumber"];

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);

$values["SocialSecurityNumber"]=$crypttext
To decrypt I'd configure View As Custom as
$key="SecretKey";

$text=$values["SocialSecurityNumber"];

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo $decrypttext;
Does that look correct?

Again, many thanks for your assistance with this.

S
salus1DevClub member 8/4/2009

Actually I think that Iwould have to create a field in the database to store the initialization vector in order to retrieve it during decrytion so...
Using this approach I would create a BeforeAdd event which looked like;
$key="SecretKey";

$text=$values["SocialSecurityNumber"];

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);

$values["SocialSecurityNumber"]=$crypttext;

$values["InitializationVector"]=$iv
To decrypt I'd configure View As Custom as
$key="SecretKey";

$text=$values["SocialSecurityNumber"];

$iv=$values["InitializationVector"]

$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo $decrypttext;
What do you think?

S
salus1DevClub member 8/4/2009

Final solution. Users can view and edit their encryped data but data is stored encrypted in database.

Ecryped data is padded (not sure how to get rid of padding yet)
textvalue is the name of the varchar field to be encrypted and stored in the database.

vector is the name of the varchar field in the database which retains the vector information generated during encrytion

__
Create Before Record Added and Before Record Updated events as follows...
$key="SecretKey";

$text=$values["textvalue"];

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $text, MCRYPT_MODE_CBC, $iv);

$values["textvalue"]=$crypttext;

$values["vector"]=$iv;
return true

__
Format textvalue field as Custom as follows...
$key="SecretKey";

$text=$data["textvalue"];

$iv=$data["vector"];

$decrypttext = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $text, MCRYPT_MODE_CBC, $iv);

$value=$decrypttext;

R
rahulgilani 8/5/2009

Final solution. Users can view and edit their encryped data but data is stored encrypted in database.

Ecryped data is padded (not sure how to get rid of padding yet)
textvalue is the name of the varchar field to be encrypted and stored in the database.

vector is the name of the varchar field in the database which retains the vector information generated during encrytion

__
Create Before Record Added and Before Record Updated events as follows...
$key="SecretKey";

$text=$values["textvalue"];

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);

$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $text, MCRYPT_MODE_CBC, $iv);

$values["textvalue"]=$crypttext;

$values["vector"]=$iv;
return true

__
Format textvalue field as Custom as follows...
$key="SecretKey";

$text=$data["textvalue"];

$iv=$data["vector"];

$decrypttext = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $text, MCRYPT_MODE_CBC, $iv);

$value=$decrypttext;


Ok, so I copied this exactly into a 5.1 installation of mine and the encryption seems to work great. However, when I get to the edit page, the information is still displayed as the encrypted characters. I've adjusted the textvalue field as Custom as you have pointed, but cannot get the decryption to work.
Any ideas what I may be doing wrong?
Thanks!

R
rahulgilani 8/6/2009

To further test, I created a sample PHP script (outside of PHP Runner) and both the encryption and decryption work, albeit, the decryption contained a couple of extra characters. I'd imagine this is the "padding" that was mentioned previously.
So, it appears whatever is happening during the View Textfield As Custom on the Edit page is not working or causing some sort of conflict. Is there any further information on this?
Thank you.

S
salus1DevClub member 8/6/2009

Hi,

The edit page will show the encrypted text as it reading it from the database but you can overwrite with new plain text and it will re-encrypt using the new values. I did not try to apply the View as Custom format to the edit page, not exactly sure what would happen...

S
salus1DevClub member 8/6/2009

The plain text is only viewable on the List and View Pages when the field has been formatted to View As Custom as outlined above. Even when I format the field on the Add and Edit Pages to View As Custom the encrypted text is read in from the dababase without modification. I did notice that after I formatted the List Page field to use the View As Custom code that the trailing characters no longer appeared. I have no idea why.

R
rahulgilani 8/6/2009

The plain text is only viewable on the List and View Pages when the field has been formatted to View As Custom as outlined above. Even when I format the field on the Add and Edit Pages to View As Custom the encrypted text is read in from the dababase without modification. I did notice that after I formatted the List Page field to use the View As Custom code that the trailing characters no longer appeared. I have no idea why.


Interesting. I wonder if I can generate the decryption on an Export function. Perhaps I won't need it on the Edit page at that time then. I do appreciate your help in this matter. Would you happen to know if the decryption works in an Export (and/or where to actually inject that code?)
Thank you in advance.

S
salus1DevClub member 8/6/2009

Hi,

Actually it looks like the data is decryted during export. The export mechanism must inherit the pages format. Also, the trailing characters are only visible when using FireFox, not Internet Exploder. I'll need to test using other browsers, too.

R
rahulgilani 8/6/2009

Hi,

Actually it looks like the data is decryted during export. The export mechanism must inherit the pages format. Also, the trailing characters are only visible when using FireFox, not Internet Exploder. I'll need to test using other browsers, too.


Hmm, interesting. Also, I've noticed that the encrypted characters are not visible in Safari, period.
Thanks for your help again.

S
salus1DevClub member 8/6/2009

Hi,

Seems to work properly in IE, Safari, and Opera, with trailing characters visble only in FireFox. All running on Vista via SSL.

R
rahulgilani 8/6/2009

Hi,

Seems to work properly in IE, Safari, and Opera, with trailing characters visble only in FireFox. All running on Vista via SSL.


Also works properly in Google Chrome. I wonder why Firefox is having an issue with it. Very strange. I think for my purposes, I'll use PHPRunner to insert the data and encrypt it, and then when it comes time to extract the data, I've created my own View page with custom PHP and that appears to work flawlessly, sans the Firefox extra characters issue.

B
barlow 8/6/2009

Sorry, I haven't read the whole thread, but this is how I've approached the same issue in PHPRUNNER 5.0

I have a 'crypt.php' file that contains the following. I include this whenever the system has to encrypt or decrypt:
crypt.php:

class Cipher {

private $securekey, $iv;

function __construct($textkey) {

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);



if($textkey == '')

$textkey="blah blah blah something special to act as a key";



$this->securekey = hash('sha256',$textkey,TRUE);

$this->iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

}

function encrypt($input) {



// 'FHT' is a tag I use to indicate an encrypted field. Then I can decrypt() everything and get

// correct output for encrypted and decrypted data, at a slight cost

return "{FHT}".base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->securekey, $input, MCRYPT_MODE_ECB, $this->iv));

}
function decrypt($input) {

if(substr($input,0,5) === "{FHT}")

{

$temp = substr($input,4);

return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->securekey, base64_decode($temp), MCRYPT_MODE_ECB, $this->iv));

}

else

return $input;

}

}


Then in PHPRUNNER I have the following in the BeforeAdd() event, for instance, to encrypt some private data:
BeforeAdd():

// Encrypt the patient details
require_once("crypt.php");
$cipher = new Cipher('');



$values["name"] = $cipher->encrypt($values["name"]);

$values["email"] = $cipher->encrypt($values["email"]);





return true;


To get the right text for the Edit page I have this in the BeforeShowEdit() event, again to handle the name and email fields:
BeforeShowEdit():

require_once("crypt.php");$cipher = new Cipher('');



$cname = $xt->xt_getvar('name_editcontrol');

$name = $cipher->decrypt($cname["params"]["value"]);

$cname["params"]["value"]=$name;



$xt->assignbyref("name_editcontrol",$cname);
$cemail = $xt->xt_getvar('email_editcontrol');

$email = $cipher->decrypt($cemail["params"]["value"]);

$cemail["params"]["value"]=$email;



$xt->assignbyref("email_editcontrol",$cemail);


Then, finally, to get a proper decrypted text in list, view, details and other pages I make a big cheat by editing commonfunctions.php in the include directory of source in the PHPRUNNER5.0 directory under Program Files:
C:\Program Files\PHPRunner5.0\source\include\commonfunctions.php:

function GetData($data,$field, $format)

{

require_once("crypt.php");$cipher = new Cipher('');



return $cipher->decrypt(GetDataInt($data[$field],$data,$field, $format));

}


This modification attempts to decrypt all data accessed by PHPRUNNER. If you look back to crypt.php above you'll see a tag used to indicate an encrypted field, so there is a little overhead in doing things this way but for my application the simplicity is worth the processing cost many times over. A further benefit is that you can add the encryption scheme to an existing database that contains unencrypted data. New data will then be encrypted, and the decrypt method will handle the old unencrypted data too. Yes, messy but it works for real-life situations.
With these mods it is easy to add encrypted fields and have PHPRUNNER code work correctly by decrypting in all the places where the encrypted data is used. Saves a lot of of 'event' code, and is perhaps the only way to go to handle 'details' pages which have no events.
Anyway that's how it happens for me, started on PHPRUNNER 4.1, so no doubt a 'custom view field' might help a lot - whatever that is. Note to self: must investigate.