Error in my encryption code in php - php

Please what could be wrong with my code? The code is meant to encrypt a given string. It does the encryption quite alright but when echoing the encrypted value, it adds numbers to the it. Here is the code:
$keys = "Bb94tU1LSSLgPKNu";
$encrypt = array();
// this contains the key/value pair i used for the encryption
$arrayEncrypt = array("a"=>"g","b"=>"h","c"=>"i","d"=>"j","e"=>"k","f"=>"l","g"=>"m","h"=>"n","i"=>"o","j"=>"p","k"=>"q","l"=>"r", "m"=>"s","n"=>"t","o"=>"u","p"=>"v","q"=>"w","r"=>"x","s"=>"y","t"=>"z","u"=>"a","v"=>"b","w"=>"c","x"=>"d","y"=>"e","z"=>"f","A"=>"G","B"=>"H","C"=>"I","D"=>"J","E"=>"K","F"=>"L","G"=>"M","H"=>"N","I"=>"O","J"=>"P","K"=>"Q","L"=>"R","M"=>"S","N"=>"T","O"=>"U","P"=>"V","Q"=>"W","R"=>"X","S"=>"Y","T"=>"Z","U"=>"A","V"=>"B","W"=>"C","X"=>"D","Y"=>"E","Z"=>"F","0"=>"2","1"=>"4","2"=>"6","3"=>"8","4"=>"0","5"=>"9","6"=>"7","7"=>"5","8"=>"3","9"=>"1");
for ($i = 0; $i < strlen($keys); $i++) {
if (array_key_exists($keys[$i], $arrayEncrypt)) {
foreach ($arrayEncrypt as $key => $letter) {
if ($keys[$i] == $key) {
// appends the values of each in $encrypt array
array_push($encrypt, $letter);
}
}
}
}
$encryptedValue = "";
foreach ($encrypt as $encrypted) {
$encryptedValue .= $encrypted;
echo $encryptedValue;
}
It prints:
H2h210z2A24R2Y2Y2R2m2V2Q2T2a2
Instead of:
Hh10zA4RYYRmVQTa

In any case, you were over complicating it trying to use the $i instead of just using the name to get the matching value. str_split() to get an array of characters then it's just a matter of $arrayEncrypt[$value]. To undo you can use array_flip().
Made you a nice function to encrypt and decrypt. Enjoy
<?php
// 1 to encrypt
// 2 to decrypt
function encdec($do, $keys){
$arrayEncrypt = array("a"=>"g","b"=>"h","c"=>"i","d"=>"j","e"=>"k","f"=>"l","g"=>"m","h"=>"n","i"=>"o","j"=>"p","k"=>"q","l"=>"r", "m"=>"s","n"=>"t","o"=>"u","p"=>"v","q"=>"w","r"=>"x","s"=>"y","t"=>"z","u"=>"a","v"=>"b","w"=>"c","x"=>"d","y"=>"e","z"=>"f","A"=>"G","B"=>"H","C"=>"I","D"=>"J","E"=>"K","F"=>"L","G"=>"M","H"=>"N","I"=>"O","J"=>"P","K"=>"Q","L"=>"R","M"=>"S","N"=>"T","O"=>"U","P"=>"V","Q"=>"W","R"=>"X","S"=>"Y","T"=>"Z","U"=>"A","V"=>"B","W"=>"C","X"=>"D","Y"=>"E","Z"=>"F","0"=>"2","1"=>"4","2"=>"6","3"=>"8","4"=>"0","5"=>"9","6"=>"7","7"=>"5","8"=>"3","9"=>"1");
if ($do==2){
$arrayEncrypt=array_flip($arrayEncrypt);
}
$chars = str_split($keys);
$encryptedValue="";
foreach($chars as $char=>$value){
$encryptedValue .= $arrayEncrypt[$value];
}
return $encryptedValue;
}
echo "Encrypted key: ".encdec(1,"Bb94tU1LSSLgPKNu")."<br />";
echo "Decrypted key: ".encdec(2,"Hh10zA4RYYRmVQTa")."<br />";
?>

Related

How to make a personal algorithm for hash in PHP

I want to make a personal algorithm for hashing texts in PHP. The letter 'a' crypt in 'xyz', 'b' in '256' and some more. How it's possible this?
It's possible by simple create a function that make characters substitution, like this:
function myEncrypt ($text)
{
$text = str_replace(array('a', 'b'), array('xby', '256'), $text);
// ... others
return $text;
}
version with two arrays "search" and "replaceWith" passed as arguments:
function myEncrypt ($text, $search=array(), $replaceWith=array())
{
return str_replace($search, $replaceWith, $text);
}
WARNING: That way isn't a correct solution to encrypt a text, there are a lot of better ways to do a secure encryption with PHP (see for example this post).
I'm bored at work so I thought i'd give this a crack.
This isn't secure at all. The crypt must be hard coded and the crypted character must have a size of 3.
<?php
//define our character->crypted text
$cryptArray = array( "a"=>"xyz","b"=>"256");
//This is our input
$string = "aab";
//Function to crypt the string
function cryptit($string,$cryptArray){
//create a temp string
$temp = "";
//pull the length of the input
$length = strlen($string);
//loop thru the characters of the input
for($i=0; $i<$length; $i++){
//match our key inside the crypt array and store the contents in the temp array, this builds the crypted output
$temp .= $cryptArray[$string[$i]];
}
//returns the string
return $temp;
}
//function to decrypt
function decryptit($string,$cryptArray){
$temp = "";
$length = strlen($string);
//Swap the keys with data
$cryptArray = array_flip($cryptArray);
//since our character->crypt is count of 3 we must $i+3 to get the next set to decrypt
for($i =0; $i<$length; $i = $i+3){
//read from the key
$temp .= $cryptArray[$string[$i].$string[$i+1].$string[$i+2]];
}
return $temp;
}
$crypted = cryptit($string,$cryptArray);
echo $crypted;
$decrypted = decryptit($crypted,$cryptArray);
echo $decrypted;
The input was : aab
The output is:
xyzxyz256
aab
Here's the 3v4l link:
https://3v4l.org/chR2A

Filter string from inside an array

I tried this:-
function sum_array($arr_sum){
$string= "";
$length= count($arr_sum);
$sum= NULL;
if(is_string($arr_sum)){
echo "You cannot use string";
}else{
for($i=0; $i<$length; $i++){
$sum = $sum + $arr_sum[$i];
}
echo " The Sum is ". $sum;
}
}
$array_summation=["string",12.6,25.2,10,12];
sum_array($array_summation);
I want to know what should i do if i want only integer or float value inside an array, and if string come inside array it gives error that no string wanted or something like that
Use array_map to get the type of each value present in the array -
$type = array_map('gettype', $array_summation);
if (!empty($type) && in_array('string', $type) {
echo "You can't use string.";
}
Try this
function sum_array($arr_sum){
$sum = 0;
foreach($arr_sum as $value){
if(!is_numeric($value)){
echo 'Array Contain non numeric data';
exit;
}
$sum += $value;
}
echo 'The sum is '.$sum;
}
$array_summation=["string",12.6,25.2,10,12];
sum_array($array_summation);
PHP has a built-in array_sum function, which ignores non-numeric strings.
$arr = [1,2,'3','apple'];
var_dump(array_sum($arr)); // int(6)
Or if you really need them to produce an error you can use array_map:
function sum_array($arr) {
if (array_sum(array_map('is_numeric', $arr)) !== count($arr)) {
echo "You cannot use string";
return;
}
echo array_sum($arr);
}
sum_array([1,2,'3','apple']); // You cannot use string
sum_array([1,2,'3','5.2']); // 11.2
Or if you want to make sure that all values in the array are either floats or integers, and not numeric strings, you can do:
function is_non_string_number($n) {
return is_float($n) || is_int($n);
}
function sum_array($arr) {
if (array_sum(array_map('is_non_string_number', $arr)) !== count($arr)) {
echo "You cannot use string";
return;
}
echo array_sum($arr);
}
sum_array([1,2,'3','apple']); // You cannot use string
sum_array([1,2,'3','5.2']); // You cannot use string
sum_array([1,2,3]); // 6

Php change a number into another number that can be changed back to the original

Using PHP, I'm trying to encode a number into another number that I can decode back to the original number. The encoded string needs to be only numbers and should not contain anything else.
Eg: 10 becomes 573563547892 or something like that.
How can I do something like this in PHP? I tried quite a few encrypt decrypt functions, but none output only numbers.
I looking for something to use in a URL that isn't easy to guess.
So: http://www.me.com/index.PHP?page=20 becomes http://www.me.com/index.PHP?page=5705254782562466
Why not using a mathematicat operation on the original number? like x becomes x * y + z. you would only have to make the reverse operation to get the original number. consider using large enough prime numbers for y and/or z
Quite heavy, but very good encryption, by using ord & chr a bit. While this works, consider other options: just being able to use strings rather then numbers already makes it a lot simpler (base64_encode etc.):
<?php
class Crypter {
private $key = '';
private $iv = '';
function __construct($key,$iv){
$this->key = $key;
$this->iv = $iv;
}
protected function getCipher(){
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');
mcrypt_generic_init($cipher, $this->key, $this->iv);
return $cipher;
}
function encrypt($string){
$binary = mcrypt_generic($this->getCipher(),$string);
$string = '';
for($i = 0; $i < strlen($binary); $i++){
$string .= str_pad(ord($binary[$i]),3,'0',STR_PAD_LEFT);
}
return $string;
}
function decrypt($encrypted){
//check for missing leading 0's
$encrypted = str_pad($encrypted, ceil(strlen($encrypted) / 3) * 3,'0', STR_PAD_LEFT);
$binary = '';
$values = str_split($encrypted,3);
foreach($values as $chr){
$chr = ltrim($chr,'0');
$binary .= chr($chr);
}
return mdecrypt_generic($this->getCipher(),$binary);
}
}
$crypt = new Crypter('secret key','12348765');
$encrypted = $crypt->encrypt(1234);
echo $encrypted.PHP_EOL;
//fake missing leading 0
$encrypted = ltrim($encrypted,'0');
echo $encrypted.PHP_EOL;
$decrypted = $crypt->decrypt($encrypted);
echo $decrypted.PHP_EOL;
Result:
057044206104214236155088
57044206104214236155088
1234

Decryption of encrypted text in PHP

I am trying to decode encrypted data in PHP, however the return value keeps coming back as null.
The data to be decrypted comes into the PHP file as a data argument.
$dataArg1 = $_REQUEST["data"];
// Retrieve $encryptedData from storage ...
//
// Load the private key and decrypt the encrypted data
$encryptedData = $dataArg1;
$privateKey = array ( array(123456,654321,123456), array(123456,1234),
array(1234567,4321)
);
openssl_private_decrypt($encryptedData, $sensitiveData, $privateKey);
The function above comes from the second response of another posting here on Stack Overflow:
How to encrypt data in javascript and decrypt in php?
I assume that the decrypted value is in the PHP variable, $sensitiveData.
When I echo that to the screen, I get nothing.
echo("sensitiveData=[$sensitiveData]<br />");
Thoughts?
UPDATE:
The return value from openssl_private_decrypt() is FALSE, and the return value is NULL.
UPDATE 2:
I created the public/private key from the following URL.
http://shop-js.sourceforge.net/crypto2.htm
At the bottom, there is the line:
And put the following in your private script (probably on your local hard disk -- not on the internet -- if your private key is found this whole thing is useless.)
<script>
function decrypt() {
// key = [ [d], [p], [q] ];
var key=[[123456789,123456789,123456789],[123456789,1234],[123456789,4321]];
document.form.text.value=rsaDecode(key, document.form.text.value);
}
</script>
(actual values changed)
I copied translated the "var key=" line to PHP (per my other posting). Translation above using embedded arrays. I then past that key to the decrypt function.
My thought is that the PHP documentation calls the private key "mixed". I am wondering if maybe I need a different format for the private key.
Here is the output:
dataArg1=[jmOdss9ktFc\"WO5eltUZXt0rpqS1NluNKa]
bResult=[]
sensitiveData=[]
var_dump=[NULL ]
$privateKey has to be in a certain format. You can't just throw in random data to it and magically expect it to know what to do with it.
Also, looking at the js you're using, it's not just doing RSA. It has a function named base64ToText. It's decoding the ciphertext with that, taking the first byte as the length of the "encrypted session key", getting the "encrypted session key", decrypting that with RSA and then using that as the key to RC4 to decrypt it. But there are a number of problems with that too. Among other things, base64ToText isn't the same thing as PHP's base64_encode as the name might imply.
Anyway I wasn't able to get it to working. Personally, I'd recommend something more like this (which is interoperable with PHP / phpseclib's Crypt_RSA):
http://area51.phpbb.com/phpBB/viewtopic.php?p=208860
That said, I did manage to figure a few things out. Your js lib uses base-28. To convert numbers from that format to one phpseclib uses you'll need to use this function:
function conv_base($num)
{
$result = pack('N', $num[count($num) - 1]);
for ($i = count($num) - 2; $i >= 0; --$i) {
_base256_lshift($result, 28);
$result = $result | str_pad(pack('N', $num[$i]), strlen($result), chr(0), STR_PAD_LEFT);
}
return $result;
}
function _base256_lshift(&$x, $shift)
{
if ($shift == 0) {
return;
}
$num_bytes = $shift >> 3; // eg. floor($shift/8)
$shift &= 7; // eg. $shift % 8
$carry = 0;
for ($i = strlen($x) - 1; $i >= 0; --$i) {
$temp = ord($x[$i]) << $shift | $carry;
$x[$i] = chr($temp);
$carry = $temp >> 8;
}
$carry = ($carry != 0) ? chr($carry) : '';
$x = $carry . $x . str_repeat(chr(0), $num_bytes);
}
Here's the script I used to confirm the correctness of that:
<?php
include('Math/BigInteger.php');
$p = array(242843315,241756122,189);
$q = array(177094647,33319298,129);
$n = array(45173685,178043534,243390137,201366668,24520);
$p = new Math_BigInteger(conv_base($p), 256);
$q = new Math_BigInteger(conv_base($q), 256);
$n = new Math_BigInteger(conv_base($n), 256);
$test = $p->multiply($q);
echo $test . "\r\n" . $n;
ie. they match.
I also ported your js's base64ToText to PHP:
function decode($t)
{
static $b64s = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"';
$r = '';
$m = $a = 0;
for ($n = 0; $n < strlen($t); $n++) {
$c = strpos($b64s, $t[$n]);
if ($c >= 0) {
if ($m) {
$r.= chr(($c << (8-$m))&255 | $a);
}
$a = $c >> $m;
$m+=2;
if ($m == 8) {
$m = 0;
}
}
}
return $r;
}
Among other potential problems I may have encountered... who knows if their RC4 implementation is correct? Their base64 implementation isn't so it wouldn't be without precedent for the RC4 implementation to be broken too.

PHP String Comparison Not Working

I am having an issue with PHP String comparison. It never turns out to be 0. Below I am trying to get a setting in a cookie and compare it with a given key, and return the value of that cookie. The cookies looks like this console=1|userId=5. The value is always -180 or something. I echo them out and the are the same, and the lengths are the same. Could it be an encoding issue?
$parameters = explode('|', $_COOKIE[Cisco_Rewards::REWARDS_SETTINGS_COOKIE_NAME]);
for ($i = 0; $i < count($parameters); $i++) {
$parameter = explode('=', $parameters[$i]);
if(count($parameter) > 1) {
echo strcasecmp(strtolower(trim($parameter[0])), trim(strtolower($name)));
if(strcasecmp(strtolower(trim($parameter[0])), trim(strtolower($name))) == 0) {
return $parameter[1];
}
}
}
You're missing break; in for loop!
Yes, it could be encoding issue because function strcasecmp() works with Unicode only. Multi-byte characters such as UTF-8 or UTF-16 cannot be compared with strcasecmp().
Also, strcasecmp() is case-insensitive function so using strtolower() against its parameters doesn't change function's result (string "example" is same as "EXAMPLE"m "eXaMPlE", "ExamPlE", etc).
You should set default result value (like $res=false;) to be sure that result is set after loop.
You should replace for loop block with foreach loop like this one bellow
$parameters = explode('|', $_COOKIE[Cisco_Rewards::REWARDS_SETTINGS_COOKIE_NAME]);
// this will handle result
$res = false;
foreach ($parameters as $value) {
$param = explode('=', $value);
if(count($parameter) > 1) {
// I guess this line is just for testing result
echo "param1=".trim($param[0])."; param2=".trim($name)."; Result=".strcasecmp(trim($param[0]), trim($name)) . "<br />\n";
if(strcasecmp(trim($param[0]), trim($name))) {
$res=$param[1];
// you should break here
break;
}
}
}
// try to output result before (testing purpose only)
var_dump($res);
return $res;
But to make this solution easy you can use this function
function getParamValue($parameters, $key) {
$res = false;
$plist = explode('|', $parameters);
foreach ($plist as $pair) {
$element = explode('=', $pair);
if (trim($element[0]) == trim($key)) {
$res = trim($element[1]);
break;
}
}
return $res;
}
So if you have $parameters string like "console=1|userid=8159" and want to find value for $key string "userid", put it into this function and it will return your result or false if $key was not found in $parameters list.
Example
$parameters = "console=1|userid=8159";
$name = "userid";
echo getParamValue($parameters, $name);
Output
8159
Now you can write your code this way
$parameters = explode('|', $_COOKIE[Cisco_Rewards::REWARDS_SETTINGS_COOKIE_NAME]);
$value = getParamValue($parameters, $name);
And $value takes your result or returns false if $name is not in $parameters list.

Categories