PHP Cryptography code explanation - java

public static function getEncryptedData($value){
if(!$value){return false;}
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, _PR_ACCOUNT_ACTIVATION_SECURE_KEY_, $text, MCRYPT_MODE_ECB, $iv);
return trim(base64_encode($crypttext)); //encode for cookie
}
I came across the above code in PHP.
I need to understand :
1. What is it doing?
2. How to do the same using Apache Shiro in Java?

/*Sets the function with the ability to be called globally without instantiating the object. Take one value into method through classname::getEncryptedData($value)*/
public static function getEncryptedData($value){
/*Checks to see if value is populated and an erroneous value hasn't been passed in such as null returns false if it has*/
if(!$value){return false;}
/* instantiated a local variable called text and populate it with the value $value*/
$text = $value;
/*as per the docs http://php.net/manual/en/function.mcrypt-get-iv-size.php gets the size of the iv and sets it in the var $iv_size*/
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
/*Creates an initialization vector as per http://uk3.php.net/manual/en/function.mcrypt-create-iv.php*/
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
/*Encrypt the data $text(from $value passed it) and store it in $crypttext */
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, _PR_ACCOUNT_ACTIVATION_SECURE_KEY_, $text, MCRYPT_MODE_ECB, $iv);
/*return a base64 encoded string with the whitespace trimmed from front and back*/
return trim(base64_encode($crypttext)); //encode for cookie
}
as for how to do it in java I dunno :-(

Related

retrofit get boolean from mysql

I have a problem with retrofit in my android app (java) retrieving a boolean field from php/mysql webservice.
In my java model, I have a boolean field selected, declared as:
#SerializedName("selected")
#Expose
private boolean selected;
In my MySQL database, the field is declared as TINYINT
When I upload my object, it is correctly saved in the database (0 or 1).
But when I want to download the same object, I get an error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected a boolean but was NUMBER at line 11 column 22 path
$[0].selected
php code:
<?php
header('content-type:application/json');
if (isset($_GET['deviceName']) && $_GET['deviceName'] != "") {
$deviceName = $_GET['deviceName'];
$sql = "SELECT * FROM `ComList` WHERE deviceName = '$deviceName' ORDER BY clistId, ord, categOrd ASC;";
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES utf8';
$bdd = new PDO('mysql:host=localhost;dbname=bdd', 'user', 'password', $pdo_options);
$bdd->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$bdd->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
$response = $bdd->query($sql);
$output = $response->fetchAll(PDO::FETCH_ASSOC);
echo(json_encode($output, JSON_PRETTY_PRINT));
?>
I can't modify the type of the field in the java model.
Any idea please?
Something to modify in the SQL request?
Modify the output in PHP?
The only way I found that give a good result is:
$output = $response->fetchAll(PDO::FETCH_ASSOC);
$tab = array();
foreach($output AS $value) {
$value['selected'] = $value['selected'] ? true : false;
array_push($tab, $value);
}
echo(json_encode($tab, JSON_PRETTY_PRINT));
But I think it's such a dirty process.

Json decode and again json encode not return same value

I have a JSON string (Created through JAVA). I can decode(PHP : json_decode) and create(PHP:json_encode) again JSON string but the return cant the same as an original JSON string. hash256 value not return same value.
$Requestbody = "{\"billerid\": \"RELENG\",\"short_name\": \"HOME91\",
\"authenticators\": [{\"parameter_name\": \"Consumer number\",\"value\":
\"155555105\"}],\"customer\": {\"customer_name\": \"OG
Test\",\"customer_mobile\": \"1231231234\",\"customer_email\":
\"agtest1#Testcomny.com\",\"customer_pan\": \"AEPM123RC4\",\"customer_aadhaar\":
\"123123123123\"},\"metadata\": {\"agent\": {\"agentid\":
\"BD001MPY100000100001\",\"sub_agentid\": \"BD001MPY11\"},\"device\":
{\"mobile\": \"9800000000\",\"geocode\": \"19.075984,72.877656\",\"postal_code\":
\"400053\",\"ip\": \"124.124.1.1\",\"channel\": \"INT\",\"branchCode\":
\"UTI00030\",\"terminalid\": \"123123\",\"imei\": \"123123123\",\"mac\": \"11-AC-
58-21-1B-AA\",\"os\": \"iOS\",\"app\": \"AGENTAPP\",\"user_agent\":
\"Mozilla\",\"dvc_fngrprnt\": \"AB22331DF49A\"}}}";
Your JSON string contains spaces after a few colons. If these are removed, the strings after json_decode and json_encode are even the same.
$Requestbody = "{\"billerid\": \"RELENG\",\"short_name\": \"HOME91\",\"authenticators\": [{\"parameter_name\": \"Consumer number\",\"value\":\"155555105\"}],\"customer\": {\"customer_name\": \"OGTest\",\"customer_mobile\": \"1231231234\",\"customer_email\":\"agtest1#Testcomny.com\",\"customer_pan\": \"AEPM123RC4\",\"customer_aadhaar\":\"123123123123\"},\"metadata\": {\"agent\": {\"agentid\":\"BD001MPY100000100001\",\"sub_agentid\": \"BD001MPY11\"},\"device\":{\"mobile\": \"9800000000\",\"geocode\": \"19.075984,72.877656\",\"postal_code\":\"400053\",\"ip\": \"124.124.1.1\",\"channel\": \"INT\",\"branchCode\":\"UTI00030\",\"terminalid\": \"123123\",\"imei\": \"123123123\",\"mac\": \"11-AC-58-21-1B-AA\",\"os\": \"iOS\",\"app\": \"AGENTAPP\",\"user_agent\":\"Mozilla\",\"dvc_fngrprnt\": \"AB22331DF49A\"}}}";
$arr = json_decode($Requestbody, true);
$str = json_encode($arr);
$cleanStr = str_replace(': ',':',$Requestbody);
var_dump($cleanStr === $str);//bool(true)
However, how #sabik correctly writes in the comment, Json strings cannot normally be compared.
In contrast to this, arrays created with json_decode ($str, true) can be compared directly.

How to extract data from a JSON array to variables and pass variables to a PHP function

I have a Java Program that sends a HTTP POST request to a PHP file. I need the PHP script to extract the JSON data to some variables and call a PHP function with those variables (parameters). Please find the PHP code below.
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$data = json_decode(file_get_contents("php://input"), true);
var_export($data);
}
else
{
var_export($_SERVER['REQUEST_METHOD']);
}
?>
The JSON Object created in Java
JSONObject json = new JSONObject();
json.put("name", "Dash");
json.put("num", new Integer(100));
json.put("balance", new Double(1000.21));
Please help me understand how to extract the JSON array data to variables And how to make the call.
Once you've run json_decode(), $data is just a "normal" php array with "normal" php values in it.
So, e.g.
/*
JSONObject json = new JSONObject();
json.put("name", "Dash");
json.put("num", new Integer(100));
json.put("balance", new Double(1000.21));
=>
*/
// $input = file_get_contents("php://input");
$input = '{"name":"Dash","num":100,"balance":1000.21}';
$data = json_decode($input, true);
$response = array(
'name_rev' => strrev($data['name']),
'num_mod_17' => $data['num'] % 17,
'balance_mul_2' => $data['balance'] * 2
);
echo json_encode($response, JSON_PRETTY_PRINT); // you might want to get rid off JSON_PRETTY_PRINT in production code
prints
{
"name_rev": "hsaD",
"num_mod_17": 15,
"balance_mul_2": 2000.42
}
two more tips:
You should test whether $data contains all the elements you expect, before accessing them, see http://docs.php.net/isset , http://docs.php.net/filter et al
a java Double() called balance. A java double is a 64-bit IEEE 754 floating point. And you might hit at one point (if not the range than) the precision limit, see What is the best data type to use for money in java app?

How can I set pageToken to get item lists from Google Cloud Storage via Java SDK?

I want to set pageToken to get items stored at Google Cloud Storage. I'm using Google API Client Library for Java v1.19.x.
I have no idea to generate pageToken from file path(or file name).
2 files stored in bucket.
my-bucket
/test.csv
/test2.csv
When I tried Google APIs Explorer with following parameters, I could get nextPageToken Cgh0ZXN0LmNzdg==.
And I found out that I can get test.csv string by decoding nextPageToken with base64.
bucket: my-bucket
pageToken:
prefix: test
maxResults: 1
{"kind": "storage#objects", "nextPageToken": "Cgh0ZXN0LmNzdg==", ...}
But How can I get Cgh0ZXN0LmNzdg== from test.csv?
Although I tried Base64 encoding, result didn't match.
import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;
String lastFile = "test.csv"
String token = Base64.encodeBase64String(lastFile.getBytes());
String bucket = "my-bucket"
String prefix = "test"
Storage.Objects.List listObjects = client.objects().list(bucket);
listObjects.setPrefix(prefix);
listObjects.setPageToken(token);
long maxResults = 1;
listObjects.setMaxResults(maxResults);
do {
Objects objects = listObjects.execute();
List<StorageObject> items = objects.getItems();
token = objects.getNextPageToken();
listObjects.setPageToken(token);
} while (token != null);
I could get next token from file path string using following codes by myself.
How to get nextToken from path string
String nextToken = base64encode(0x0a + asciiCode + pathString)
asciiCode can be taken between 0x01(SOH) and 0x7f(DEL). It seems to depend on path length.
my-bucket/
a/a(3byte) 0x03
a/ab(4byte) 0x04
test.txt(8byte) 0x08
Notice
If path length is longer than 1024 byte, another rule seems to apply. But I couldn't found out rules.
See also Object Name Requirements
import com.google.common.io.BaseEncoding;
String lastFile = "test.csv"
String token = base64Encode(lastFile);
String bucket = "my-bucket"
String prefix = "test"
Storage.Objects.List listObjects = client.objects().list(bucket);
listObjects.setPrefix(prefix);
listObjects.setPageToken(token);
long maxResults = 1;
listObjects.setMaxResults(maxResults);
do {
Objects objects = listObjects.execute();
List<StorageObject> items = objects.getItems();
token = objects.getNextPageToken();
listObjects.setPageToken(token);
} while (token != null);
private String base64Encode(String path) {
byte[] encoding;
byte[] utf8 = path.getBytes(Charsets.UTF_8);
encoding = new byte[utf8.length + 2];
encoding[0] = 0x0a;
encoding[1] = new Byte(String.valueOf(path.length()));
String s = BaseEncoding.base64().encode(encoding);
return s;
}
I know this question is already answered and is applied to Java, I'd like to mention that this question applies to PHP as well.
With the help of the approved post from sakama above I figured out a PHP version of his solution.
The PHP equivalent for generating the token is as follow:
base64_encode(pack('c', 0x0a) . pack('c', $path_string_length) . pack('a*', $path_string));
The byte pattern seems indeed (as sakama already mentioned) to be:
<line feed><line data length><line data>

Is there a way to use commutative encryption in php?

I have used the encrypt and decrypt functions from this answer to implement message passing using Three-pass protocol with the Blowfish cipher.
And I tried using commutative ecryption/decryption. That is,
$tmp = encrypt($input, $key1);
$tmp = encrypt($tmp, $key2);
$tmp = decrypt($tmp, $key1);
$dec2 = decrypt($tmp, $key2);
But it does not work. I used a single key instead of 2 different keys and it works(has to!).
So there's no problem in the way I'm using these functions, but I simply cant get it working with two keys.
Am I doing something wrong? Is this not possible, or is there another way?
Or, is there a way I could do it in Java?
Edit: For those who don't understand the procedure, Three-pass protocol is a way to send encrypted messages without having to send the keys. So the procedure is
Sender encrypts with key1 and sends
Receiver encrypts with key2 and sends back
Sender decrypts with key1 and sends back
Receiver decrypts with key2 to get the original message
You can see that keys are not exchanged, but the message is sent only in encrypted form. That's the whole point.
Using the XOR function provided by a user in this thread
Encrypt/decrypt with XOR in PHP
function xor_this($string,$key) {
// Our plaintext/ciphertext
$text =$string;
// Our output text
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);)
{
for($j=0;($j<strlen($key) && $i<strlen($text));$j++,$i++)
{
$outText .= $text{$i} ^ $key{$j};
//echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
}
}
return $outText;
}
//The sender chooses a private encryption key s and a corresponding decryption key t. The sender encrypts the message m with the key s and sends the encrypted message E(s,m) to the receiver.
//The receiver chooses a private encryption key r and a corresponding decryption key q and super-encrypts the first message E(s,m) with the key r and sends the doubly encrypted message E(r,E(s,m)) back to the sender.
//The sender decrypts the second message with the key t. Because of the commutativity property described above D(t,E(r,E(s,m)))=E(r,m) which is the message encrypted with only the receiver's private key. The sender sends this to the receiver.
$senderkey=base64_encode('chicken');
$receiverkey=base64_encode('ardvark');
$itemwewanttoshare='hello darling';
echo'$itemwewanttoshare: '.$itemwewanttoshare.'<BR>';
$packet1=xor_this($itemwewanttoshare,$senderkey);
echo'$packet1: '.$packet1.'<BR>';
$packet2=xor_this($packet1,$receiverkey);
echo'$packet2: '.$packet2.'<BR>';
$packet3=xor_this($packet2,$senderkey);
echo'$packet3: '.$packet3.'<BR>';
$packet4=xor_this($packet3,$receiverkey);
echo'$packet4: '.$packet4.'<BR>';
You get this
$itemwewanttoshare: hello darling
$packet1: 1W6 TS>
$packet2: hNwRVtq|ing
$packet3: 1=&M"TS>
$packet4: hello darling
EDIT addition
I base64'd the key for simplicity. Use a key with more variation and the results will be more complicated.
use mcrypt_create_iv(40) to create your keys and you end up with something like this
$senderkey='<²#H[Ô\´(µÑ/KÀ®"熺¥ç|Ëvr%O›eu$nºbe';
$receiverkey='Øh\5PÀKO[ù¬òZH‰•Ê¬h/¥nëk¾ðéíPÄ"Uü';
which will change the output to
$itemwewanttoshare: hello darling
$packet1: T§ÞO'{§õ.®ÝF¥
$packet2: —?¶+¦6®½– þ
$packet3: «ý0Zpe¢ò"!<
$packet4: hello darling
Edit 2
Duskwuff brings up a good point. $itemwewanttoshare should be created by the system(program) and not be a user created item. This method could be used to establish a shared encryption key that both send and receiver could use to encrypt further communication. Sender would generate the key, and then that would be the itemwewanttoshare , thus allowing both sides to know the encryption key without passing it directly.
The WikiPedia article gives a hint at what can be used:
Sometimes the encryption function and decryption function are the same.
This is the case for stream ciphers like RC4 which create a long stream of pseudo-random data and simply XOR it with the data. XOR is commutative and it is easy to implement it in PHP:
$cipher = "arcfour";
$k1 = mcrypt_create_iv(256); // random
$k2 = mcrypt_create_iv(256); // random
$data = "some string";
$mode = "stream";
echo "key size: ".mcrypt_get_key_size($cipher, $mode)."\n"; // 256
echo "iv size: ".mcrypt_get_iv_size($cipher, $mode)."\n"; // 0
// Three-pass protocol property: D(d,E(k,E(e,m))) = E(k,m)
$c1 = mcrypt_encrypt($cipher, $k1, $data , $mode, "");
$c2 = mcrypt_encrypt($cipher, $k2, $data , $mode, "");
$c2 = mcrypt_encrypt($cipher, $k1, $c2 , $mode, "");
$c2 = mcrypt_decrypt($cipher, $k2, $c2 , $mode, "");
echo $c1 == $c2;
Block ciphers in CTR mode are also useable in the same way. This is an example of AES in CTR mode:
$cipher = "rijndael-128";
$k1 = mcrypt_create_iv(16); // random
$k2 = mcrypt_create_iv(16); // random
$iv1 = mcrypt_create_iv(16); // random
$iv2 = mcrypt_create_iv(16); // random
$data = "some string";
$mode = "ctr";
echo "key size: ".mcrypt_get_key_size($cipher, $mode)."\n";
echo "iv size: ".mcrypt_get_iv_size($cipher, $mode)."\n";
$c1 = mcrypt_encrypt($cipher, $k1, $data , $mode, $iv1);
$c2 = mcrypt_encrypt($cipher, $k2, $data , $mode, $iv2);
$c2 = mcrypt_encrypt($cipher, $k1, $c2 , $mode, $iv1);
$c2 = mcrypt_decrypt($cipher, $k2, $c2 , $mode, $iv2);
echo $c1 == $c2;

Categories

Resources