I'm trying to decrypt a string in PHP, I can do it in JS, but I can't do it via PHP.
New in cryptography, I try to recover my original string, but it can't find a solution.
So I have this code below in JS :
const p1 = ['abc', 1, 'def', 'hij'].join('a');
let p2 = crypto.createHash('md5').update(p1, 'ascii').digest('hex') + 'a' + p1 + 'a';
while (p2.length % 16 > 0) p2 += ' ';
let result = crypto.createCipheriv('aes-128-ecb', 'aeda94ad8azd', '').update(p2, 'ascii', 'hex');
this code in PHP :
$p1 = implode('a', ['abc', 1, 'def', 'hij']);
$p2 = hash('md5', $p1, false) . 'a' . $p1 . 'a';
dd($p2);
while (strlen($p2) % 16 > 0) $p2 .= ' ';
$result = openssl_encrypt($p2, 'aes-128-ecb', 'aeda94ad8azd', 0);
JS Result :
let p2 result = 7fbe3256bd8e9ac3e9b2e2ac9c1c812aaabca1adefahija
p2 result after while = same as P2 with one space at the end
let result = a7222dbd06b1ae0ea421ac968eba780f0e0e23317c25bab0ecf423b6ff95f1e25ede0432af1a8b17c56e682193c55516
PHP Result :
$p2 result = 7fbe3256bd8e9ac3e9b2e2ac9c1c812aaabca1adefahija
$p2 result after while = same as p2 with one space at the end
$result = wE5FpEuPuWdL8D06y/jiqRB7kehRcLcBmI16AncqsKWeeqWm8Tj08anFBrnD0JWCP5/ihLo0AUZr0/+MBDjQvw==
I do something wrong in openssl_decrypt ? I don't use the right function ?
Waiting for your help thank you all.
Have a nice day
I gave it a try, but you're using Javascript in Node.js which I don't use. Still, it could be useful to give an answer because I got somewhat closer to the result you want.
First of all I noticed that your JS result is in hexadecimal whereas the PHP result is probably in Base64. Some conversion is required. I had to use the raw result, and remove the padding to get a hexadecimal string that's as long as yours. The PHP code is:
$raw = openssl_encrypt($p2,
'aes-128-ecb',
'aeda94ad8azd',
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
$result = bin2hex($raw);
Now the result is:
c04e45a44b8fb9674bf03d3acbf8e2a9107b91e85170b701988d7a02772ab0a59e7aa5a6f138f4f1a9c506b9c3d09582
Same type (hexadecimal) and length of string, but not the same. There are two things that could cause the difference:
The character encoding of the file. I can't check the node.js one.
The keys might be treated differently. In node.js it has to be in UTF-8 and I think it is binary in PHP.
Anyway, I hope this is somewhat useful.
Related
how would I convert an integer to an array of 4 bytes?
Here is the exact code I want to port (in C#)
int i = 123456;
byte[] ar = BitConverter.GetBytes(i);
// ar will contain {64, 226, 1, 0}
How would I do the exact same thing in PHP ?
The equivalent conversion is
$i = 123456;
$ar = unpack("C*", pack("L", $i));
See it in action.
You should be aware though that the byte order (little/big endian) is dependent on the machine architecture (as it is also in the case of BitConverter). That might or might not be good.
Since the equivalent of a byte array in PHP is a string, this'll do:
$bytes = pack('L', 123456);
To visualize that, use bin2hex:
echo bin2hex($bytes);
// 40e20100
// (meaning 64, 226, 1, 0)
I am sure this is because of the "g" on the end but this is the scenario and results when I try and work out a ratio percent. I always want to divide the highest of 2 numbers by the lowest.
$item1 = "200.00g";
$item2 = "50.00g";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
// result: $calc = "400%"
$item1 = "100.00g";
$item2 = "5.00g";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
// result: $calc = "2000%"
PROBLEM RESULT:
$item1 = "8.00g";
$item2 = "14.00g";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
// result: $calc = "57%"
// I am expecting (14.00g / 8.00g)*100 = "175%"
It's type casting;
$item1 = "8.00";
$item2 = "14.00";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
result will be 175%
When you want to use your strings in mathematical operations, and you know that the unit is placed at the end as it is in your example, you can cast your variables to floats:
$item1_numeric = (float) $item1;
But obviously it is better to have the values and the units separated in your variables / database.
Use: substr($item1, 0, -1) instade of $item1, substr($item2, 0, -1) instade of $item2 when you do round.
You can't compare 2 strings with round().
Edit : If $item1 = "200g", ma solution is ok, but if if $item1 = "200.00g" you need to remove "." before round() with for example pregreplace.
Oh, YAPHPB - and one of my favorite ones. Even though it's written in the Doc:
When [max()] given a string it will be cast as an integer when comparing.
... it's only a partial truth: if at least one of compared values is a number, or a numeric string.
Otherwise all the strings will be compared as strings: first {0} characters of each strings will be compared, then {1}, then {2}... etc.
So basically that's what happens here:
echo max("200.00g", "50.00g"); // 50.00g, as '5' > '2'
echo max("200.00g", 50); // "200.00g", as it gets converted to int (become 200)
And that's even more crazy:
echo max("200.00g", "1000.00"); // "200.00g", as '2' > '1'
echo max("200.00", "1000.00"); // "1000.00", as we tried to help you, no, really!
The latter result can actually be predicted by someone knowing of numeric concept: when both strings are pure numbers, they got converted to numbers when compared. Still, I found this behavior unreliable, to say the least.
The bottom line: if you need to compare numbers, compare numbers, period. Type conversion in PHP can get real messy - and bite you in the bottom real hard when you least expect it. )
I am trying to pass over from php a string into C++, i managed to figure out how to pass numbers, but it doesn't work for letters. Here's what i have that works for PHP
<?php
$r = 5;
$s = 12;
$x= 3;
$y= 4;
$q= "Hello World";
$c_output=`project1.exe $r $s $x $y $q`; // pass in the value to the c++ prog
echo "<pre>$c_output</pre>"; //received the sum
//modify the value in php and output
echo "output from C++ programm is" . ($c_output + 1);
?>
This sends the variables r,s,x,y, and q to the C++ programm project1.exe and IT WORKS, but the problem is that it doesn't work for the string variable $q.
Here's the code that I have in my C++ programm, it's simple:
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
int main(int in, char* argv[]) {
int val[2];
for(int i = 1; i < in; i++) { // retrieve the value from php
val[i-1] = atoi(argv[i]);
}
double r = val[0];
double s = val[1];
double x = val[2];
double y = val[3];
double q = val[4]; // here's the problem, as soon as i try to define val[4] as a string or char, it screws up
cout << r;
cout <<s;
cout << x;
cout << y;
cout << q;
// will output to php
return 0;
}
It works, but for the string "Hello world" which i pass through $q from PHP doesn't give me the string back (i know it's defined as a double, but as soon as i try to change it to a string or a char variable the code just doesn't compile).
Please explain to me how i have to go around this problem so that $q can be processed as a string. FYI, I am a newbie to programming (6 months in).
Try not converting the final argument using atoi(argv[i]). Just keep it as argv[i].
for(int i = 1; i < in-1; i++)
{
val[i-1] = atoi(argv[i]);
}
q = argv[i];
It doesn't work for letters because you are doing atoi(..)(which converts char-string to integer) in the C++ program.
Have some means of letting the program know what to expect -- whether a number or a string. May be the first argument can help the program differentiate, like may be the following:
$c_output = `project1.exe nnsnns 1 2 string1 3 4 string2`
Then you could do:
for(int i = 0/*NOTE*/,len=strlen(argv[1]); i < len; i++) { // retrieve the value from php
if (argv[1][i] == 'n'){
//argv[2+i] must be an integer
}else if (argv[1][i] == 's'){
//argv[2+i] is a string
}
}
Of course you should check if (strlen(argv[1]) == in-2).
BTW, in the C++ code above, val is a array holding 2 ints; and you are trying to access much beyond index 1.
To pass one single string to the C++ you would do something like the following:
$output = `project1.exe $q`; //Read below.
NOTE: $q must be a single word. No spaces, no extra characters like '|', '&', or any other character which the shell might interpret differently. $q must be clean before you pass that on to C++ Program. If $q is more than one word, use quotes.
C++ Part (Just try the following, then you can modify as you go along)
cout<<argv[1]<<endl;
This is not about security. It is also not to make it hard to break. I'm looking for a simple algorithm to change a string (a url) in a way it does not resemble the original. The encryption will be done with javascript. Then I want to feed the encrypted string to a PHP function to change it back to the original. Both ends could share a secret key, or the conversions could be key-less and rely on just logic.
The ideal solution
will be simple
will use available javascript functions for encryption
will use available php functions for decryption
will produce encrypted string in way not to resemble the plain text at all
will only use lower-case alphabet characters and numbers in the encrypted string
is not a method widely used like Base64-ing as encryption.
Edit: The last requirement was added after shamittomar's answer.
You can use bitwise XOR in javascript to encode the string and again in PHP to decode it again. I wrote a little Javascript example for you. It works the same in PHP. If you call enc() a second time with the already encoded string, you'll get the original string again.
<html>
<head><title></title></head>
<body>
<script type="text/javascript">
function enc(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 123; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
var str = "hello world";
var encoded = enc(str);
alert(encoded); // shows encoded string
alert(enc(encoded)); // shows the original string again
</script>
</body>
</html>
In PHP do something like this (caution, this is not tested and it's been a long while since I did PHP):
$encoded = "..."; // <-- encoded string from the request
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
$b = ord($encoded[$i]);
$a = $b ^ 123; // <-- must be same number used to encode the character
$decoded .= chr($a)
}
echo $decoded;
If that's what you want, you can Base64 encode and decode that.
[EDIT]: After OP clarification:
As you do not want widely used methods, here is one rarely used method and that can do it for you by giving output only in LOWERCASE letters and NUMBERS. It is Base32 Encode/Decode. Use the following libraries:
Javascript Base32 Encoder: http://www.tumuski.com/2010/04/nibbler/
PHP Base32 Decoder: https://www.phpclasses.org/package/3484-PHP-Encode-and-decode-data-with-MIME-base-32-encoding.html
If it's not about security, and not about making it hard to break, then how about ROT-13?
//+ Jonas Raoni Soares Silva
//# http://jsfromhell.com/string/rot13 [rev. #1]
String.prototype.rot13 = function(){
return this.replace(/[a-zA-Z]/g, function(c){
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
};
...
var s = "My String";
var enc = s.rot13(); // encrypted value in enc
PHP has a native function, str_rot13: http://php.net/manual/en/function.str-rot13.php
$decrypted = str_rot13($_GET['whatever']);
Well I found this page and found Redcully's program not work for me so I thought It happens with all others. finally I got reason and fixed it. Here new code is...
Thanks to Redcully :)
JS function:
function encode(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 51; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
PHP function:
function decode($encoded) {
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
$b = ord($encoded[$i]);
$a = $b ^ 51; // <-- must be same number used to encode the character
$decoded .= chr($a);
}
return $decoded;
}
How are you planning to implement (hide) the secret in Javascript? IMHO it's not possible.
Edit: OK - not about security.. then just use any baseXX or rot encoding mechanism. But you can't really say one of these algorythms would not be well known...
I need help to change a character in php.
I got some code from the web:
char dest='a';
int conv=(int)dest;
Can I use this code to convert a character into numeric? Or do you have any ideas?
I just want to show the result as a decimal number:
if null == 0
if A == 1
Use ord() to return the ascii value. Subtract 96 to return a number where a=1, b=2....
Upper and lower case letters have different ASCII values, so if you want to handle them the same, you can use strtolower() to convert upper case to lower case.
To handle the NULL case, simply use if($dest). This will be true if $dest is something other than NULL or 0.
PHP is a loosely typed language, so there is no need to declare the types. So char dest='a'; is incorrect. Variables have $ prefix in PHP and no type declaration, so it should be $dest = 'a';.
Live Example
<?php
function toNumber($dest)
{
if ($dest)
return ord(strtolower($dest)) - 96;
else
return 0;
}
// Let's test the function...
echo toNumber(NULL) . " ";
echo toNumber('a') . " ";
echo toNumber('B') . " ";
echo toNumber('c');
// Output is:
// 0 1 2 3
?>
PS:
You can look at the ASCII values here.
It does indeed work as in the sample, except that you should be using php syntax (and as a sidenote: the language that code you found most probably was, it did not do the same thing).
So:
$in = "123";
$out = (int)$in;
Afterwards the following will be true:
$out === 123
This may help you:
http://www.php.net/manual/en/function.ord.php
So, if you need the ASCII code you will need to do:
$dest = 'a';
$conv = ord($dest);
If you want something like:
a == 1
b == 2
.
.
.
you should do:
$dest = 'a';
$conv = ord($dest)-96;
For more info on the ASCII codes: http://www.asciitable.com/
And for the function ord: http://www.php.net/manual/en/function.ord.php
It's very hard to answer because it's not a real question but just a little bit of it.
But if you ask.
It seems you need some translation table, that defines links between letters and numbers
A -> 2
B -> 3
C -> 4
S -> 1
or whatever.
You can achieve this by using an array, where keys would be these letters and values - desired numbers.
$defects_arr = array(
'A' -> 2,
'B' -> 3,
'C' -> 4'
'S' -> 1
};
Thus, you can convert these letters to numbers
$letter = 'A';
$number = $defects_arr($letter);
echo $number; // outputs 1
But it still seems is not what you want.
Do these defect types have any verbose equivalents? If so, why not to use them instead of letters?
Telling the whole story instead of little bit of it will help you to avoid mistakes and will save a ton of time, both yours and those who to answer.
Out of this question, if you are looking for convert RT0005 to 5
$max = 'RT0005';
return base_convert($max,10,10);
// return 5