json_encode does not work on encrypted string - php

I'm having a little trouble, as i want to encrypt some post data i get from a form and then send them to my nodejs server in json format to put them into a database.
My Problem: i seem to be unable to post the data once it is encrypted. I can post the json string just fine, but not anything more:
My code:
$rsa->loadKey($keydata);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$encrypted = $rsa->encrypt("test");
$jsonArray = array(
'crypt' => $encrypted
);
$jsonArrayEncoded = json_encode($jsonArray);
echo $jsonArrayEncoded;
$ch = curl_init('https://..........');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonArrayEncoded);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
I don't even get the echo output. But the string seems to get encrypted, as i can echo that (a lot of charset errors + some random letters and numbers) and if i decode it in the php skript i get the correct result as well. I don't get any console warnings or errors, neither in chrome, nor firefox.
Anything i do wrong? (quite sure there is)
e: I'm using this as crypto library: http://phpseclib.sourceforge.net/rsa/examples.html#encrypt,enc1
edit2: well, as adviced in the comments i converted the string to utf8, but now it seems to be too long to be decrypted with my key... Tough o only encrypted the word "test"...
I think i have to dig deeper...
If anyone knows: for decryption I'm using the Ursa module for node.js with following code:
var buffer = new Buffer(req.body.crypt);
var data = private.decrypt(buffer, 'utf8', 'utf8', ursa.RSA_PKCS1_PADDING);

well, as adviced in the comments i converted the string to utf8, but
now it seems to be too long to be decrypted with my key... Tough o
only encrypted the word "test"...
It'd help to see your updated code that does that. In lieu of doing that...
json_encode doesn't natively handle binary data. My recommendation would be to do something like this:
$jsonArray = array(
'crypt' => bin2hex($encrypted)
);
$jsonArrayEncoded = json_encode($jsonArray);
echo $jsonArrayEncoded;
You'd need to compress it back down to binary, though, after you json decode'd it in Java.
Alternatively, you could do base64_encode and base64 decode it later.
The concern I'd have with utf8 encoding is that PHP's internal string type isn't utf8. If Java's is then that could cause problems it seems.

The json_encoding function has numerous flags that you can pass to it, which enable the function to parse particular character sets. The following call might solve the problems you are having
json_encode($jsonArray, JSON_UNESCAPED_SLASHES | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP );

Related

Bad JSON being returned from Survey Monkey (get_survey_list)

I've been trying to pull Survey Data for a client from their Survey Monkey account, it seems that the more data their is the more likely illegal characters are introduced in to the resulting JSON string.
Below is a sample of what is returned on a bad response, every response is different and even shorter requests some times fail leaving me at a miss.
{
"survey_id": "REDACTED",
"title": "REDACTED",
"date_modified": "2014-XX-18 17:59:00",
"num_responses": 0,
"date_created": "�2014-01-21 10:29:00",
"question_count": 102
}
I can't fathom as to why this is happening, the more parameters in the fields option there are, the more illegal characters are introduced. It isn't just illegal invalid characters, some times random letters are thrown in as well which prevents me from handling the data correctly.
I am using Laravel 4 with the third party Survey Monkey library by oori
https://github.com/oori/php-surveymonkey
Any help would be appreciated in tracking down the issue, the deadline is pretty tight and if this can't be resolved I'll have to resort to asking the client to manually import CSV files which isn't ideal and introduces possible user error.
On a side note, I don't see this issue cropping up when using the same parameters on the Survey Monkey console.
O/S: Windows 8.1 with WAMP Server
Code used to execute the request
$Surveys = SurveyMonkey::getSurveyList(array
(
'page_size' => 1000,
'fields' => array
(
'title', 'question_count', 'num_responses', 'date_created', 'date_modified'
)
));
The SurveyMonkey facade is a custom package used to integrate the original Survey Monkey library located here:
https://github.com/oori/php-surveymonkey/blob/master/SurveyMonkey.class.php
Raw PHP cURL request
$header = array('Content-Type: application/json','Authorization: Bearer REDACTED');
$post = json_encode(array(
'fields' => array(
'title', 'question_count', 'num_responses', 'date_created', 'date_modified'
)
));
$post = json_encode($post);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.surveymonkey.net/v2/surveys/get_survey_list?api_key=REDACTED");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result = curl_exec($ch);
The above request returns the same troublesome characters, nothing else was used to get the response.
Using the following code
echo "\n".mb_detect_encoding($result, 'UTF-8', true);
This code shows the charset for the response, when successful and no illegal characters are present (there are still random characters in the wrong places) it returns that it is in fact UTF-8, when illegal characters are present false is returned so nothing is outputted. More often than not, false is returned.
Maybe I'm grossly oversimplifying the whole thing and apologies if so, but I have had these funny little chars pop in to results, too.
They were leading and trailing whitespace.
Can you trim data on retrieve and see if it still happens?

Failed to send SMS in Hindi

I need to send SMS in hindi, for this I need to pass the hindi string through URL.
As I am coading in php I used urlencode($hindimessage) on string and passed complete URL through file_get_contents(). On executing I got error:
Warning: file_get_contents(http://IP GOES HERE/smpp/sendsms?username=$name&password=******&to=$contact&from=DEMOTT&coding=3&&text=%E0%A4%AE%E0%A4%A8%E0%A5%80%E0%A4%B7+%E0%A4%95%E0%A5%81%E0%A4): failed to open stream: HTTP request failed! HTTP/1.1 505 HTTP Version Not Supported
Without using urlencode(), the server treats text as EMPTY STRING and rejects.
I also tried Using utf8_encode() encoding. I recive message in HTML tags like ही....
But when I use the API URL directly I am able to recive the message in hindi since API is Unicode API coding=3 enbled for Hindi text.(i.e API is working Properly)
Please Inform what kind of approach I need to adopt for sending message in both Hindi as well as in English.
Thanks in Advance
urlencode() is necessary if you are calling URL in file_get_contents() function.
You need to adopt CURL for sending message in both Hindi as well as in English.
$smsgatewayurl = 'http://IP GOES HERE/smpp/sendsms';
$post_data = array(); // All params including text message
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $smsgatewayurl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
curl_close($ch);
CURL is best option to call third party APIs compare to file_get_contents function. I have tested this above function with spring edge sms gateway including hindi text.
Set dcs coding =8 and convert your Hindi characters into Unicode characters and put it in the text field.This will work.

How do i post a long string into a PHP page?

This question has two parts:
Part I - restriction?
I'm able to store data to my DB with this:
www.mysite.com/myscript.php?testdata=abc123
This works for a short string (eg 'abc123') and the page echos what was written to the DB; however, if the [testdata=] string is longer than 512 chars and i check the database, it shows a row has been added but it's blank and also my echo statement in the script doesn't display the input string.
N.B. I'm on a shared server and have emailed my host to see if it's a restriction.
Part II - best practice?
If i can get past the above hurdle, I want to use a string that's ~15k chars long created in a desktop app that concatenates the [testdata=] string from various parameters; what's the best way to send a long string in PHP POST?
Thanks in advance for your help, i'm not too savvy with PHP.
Edit: Table config:
Edit2: Row anomaly with long string > 512 chars:
Edit3: here's my PHP script, if it helps:
<?
include("connect.php");
$data = $_GET['testdata'];
$result = mysql_query("INSERT INTO test (testdata) VALUES ('$data')");
if ($result) // Check result
{
echo $data;
}
else echo "Error ".$mysqli->error;
mysql_close(); ?>
POST is definitely the method you want to use, and your best bet with that will be with cURL. Something like this should work:
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "http://www.mysite.com/myscript.php" );
curl_setopt( $ch, CURLOPT_POST, TRUE );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $my_really_long_string );
$data = curl_exec( $ch );
You'll need to modify the above to include additional cURL options as per your environment, but something like this is what you'd be looking for.
You'll want to make sure that your DB field is long enough to hold the really long string as well.
Answer 1 Yes, max length of url has restriction. See more:
What is the maximum possible length of a query string?
Answer 2 You can send your string like simple varible ($_POST). Check only settings for max vals of inputing/exectuting in php.ini.

Send UTF-16 encoded data with PHP curl

I'm building a php client to a web service that requires posted data to be encoded as UTF-16. How do i configure curl to encode my data in UTF-16 and also to decode the answer in UTF-16?
Some sample code:
$s = curl_init($url);
curl_setopt($s,CURLOPT_POST,1);
curl_setopt($s,CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($s,CURLOPT_POSTFIELDS,$data);
curl_setopt($s,CURLOPT_TIMEOUT, 5);
curl_setopt($s,CURLOPT_HTTPHEADER,array('Content-Type: text/plain'));
$result = curl_exec($s);
curl_close($s);
Adding an Accept-Encoding header does not seem to do the trick. Is it possible to encode my $data string in UTF-16 first and then pass a byte array to curl instead of a string?
Thank you for your answers!
First, you need to find out what's your data encoding. Then, it's your choice. Both iconv() and mb_convert_encoding() work pretty well.
Additionaly, you should inform about the encoding in the HTTP header:
curl_setopt($s,CURLOPT_HTTPHEADER,array('Content-Type: text/plain; charset=UTF-16'));

How big is a string in PHP?

If I download a file from a website using:
$html = file_get_html($url);
Then how can I know the size, in kilobyes, of the HTML string? I want to know, because I want to skip files over 100Kb.
If you do file_get_contents, you've already gotten the whole file.
If you mean "skip processing", rather than "skip retrieval", you can just get the length of the string: strlen($html). For kilobytes, divide that by 1024.
This is imprecise because the string may contain UTF-8 characters over one byte in length, and very small files will actually occupy a FS block instead of their byte length, but it's probably good enough for the arbitrary-threshold cutoff you're looking for.
To skip fetching large files, you want to use the cURL library.
<?php
function get_content_length($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
$hraw=explode("\r\n",curl_exec($ch));
curl_close($ch);
$hdrs=array();
foreach($hraw as $hdr) {
$a=explode(": ", trim($hdr));
$hdrs[$a[0]]=$a[1];
}
return (isset($hdrs['Content-Length'])) ? $hdrs['Content-Length'] : FALSE;
}
$url="http://www.example.com/";
if (get_content_length($url) < 100000) {
$html = file_get_contents($url);
print "Yes.\n";
} else {
print "No.\n";
}
?>
There may be a more elegant way to pull this information out of curl, but this is what came to mind fastest. YMMV.
Note that setting the CURLOPT options this way makes curl use a "HEAD" rather than "GET" request, so we're not actually fetching this URL twice.
The definition, what a string is, is different between PHP and the intuitive meaning:
"Hällo" (mind the Umlaut) looks like a 5-character String, but to PHP it is really a 6-byte array (assuming UTF8) - PHP doesn't have a notion of a String representing text, it just sees it as a sequence of bytes (The PHP euphemism is "binary safe").
So strlen("Hällo") will be 6 (UTF8).
That said, if you want to skip above 100Kb you probably won't mind if it is 99.5k characters translating to 100k bytes.
file_get_html returns an object to you, the information of how big the string is is lost at that point. Get the string first, the object later:
$html = file_get_contents($url);
echo strlen($html); // size in bytes
$html = str_get_html($html);
You can use mb_strlen to force 8bit or what not and then 1 character = 1 byte

Categories