Zend mcrypt-aes without special characters in the encrypted text - php

I am using the zend mcrypt function for the encryption of a text.
The encryption is done using the code below,
use Zend\Crypt\BlockCipher;
use Zend\Crypt\Symmetric\Mcrypt;
$blockCipher = new BlockCipher(new Mcrypt(array('algo' => 'aes'));
$blockCipher->setKey('enCryKey');
$result = $blockCipher->encrypt('this is a secret message');
echo "Encrypted text: $result \n";
There are some special characters appearing in the encrypted text. But, i have to use this in a URL and i don't want any special characters in the URL, because of url encoding difference for different mails.
Is there any way to avoid the special characters from the encrypted text which uses zend mcrypt(aes) for encryption?

Related

php simple encode decode function using only (0-9 A-Z a-z)

I'm setting up a PHP email tracking system that uses url parameters to track link click throughs. Something like:
www.example.com?trackToken=10
I'm looking for a simple PHP encode / decode function I can put in place that will take a number (in this case 10) and convert in to strictly to number and letters. something like:
www.example.com?trackToken=7aj8nG93nDpw9M9Nk1
I have found several variations of encrypt / decrypt functions using mcrypt. However, the encrypted output always ends up containing strange characters. These strange characters make it hard for my email messages to be sent/delivered.
Does anyone know of a good encrypt function that only outputs numbers 0-9 and letters a-z or A-Z? Additionally, I'm looking for a decrypt function to complement the encrypt function so I can actually use it.
I'm not looking for something super secure here. Just a way to mask the actual tracking token so the user can't change it on their own.
Base64 should be fine in any modern system - and any system handling email in PHP fits the definition of "modern". There is absolutely no reason I can think of to limit to just alphanumerics. The only catch is that as a URL parameter you don't want to have a '+' or '/' in the string. There is base64url to solve this problem but that doesn't have a standard PHP function. You can easily replicate that by using base64_encode() and str_replace() and to decode str_replace followed by base64_decode():
$coded = str_replace('+','-',str_replace('/','_',base64_encode($original)));
$original = base64_decode(str_replace('_','/',str_replace('-','+',$coded)));

How can I base64_encode and base64_decode string with html tags?

I have a problem with base64 decode
For example, I have this code:
else if($_POST['submit']==2){
$send = base64_encode($text_success);
wp_redirect( home_url('/sales-funnel/add-product?msg='.$send) ); exit;
}
I send encoded string to page, so that user can't simply read it from url.
$text_success contain html code, which is generated if $wpdb->query not contain errors:
`Darījums veiksmīgi pievienots!</br>Komentārs veiksmīgi pievienots!</br>Klients veiksmīgi pievienots!</br>Fāze ir pievienota! </br>`
In all online base64_decode it's works great, but my WordPress site return empty string when I'm trying to do:
if (isset($_GET['msg']) && !empty($_GET['msg'])){
$text = base64_decode($_GET['msg']);
echo $text;
}
But, $_GET['msg'] = RGFyxKtqdW1zIHZlaWtzbcSrZ2kgcGlldmllbm90cyE8L2JyPktvbWVudMSBcnMgdmVpa3NtxKtnaSBwaWV2aWVub3RzITwvYnI+S2xpZW50cyB2ZWlrc23Eq2dpIHBpZXZpZW5vdHMhPC9icj5GxIF6ZSBpciBwaWV2aWVub3RhISA8L2JyPg==
P.S. I tried to use it without html tags, all works great.
The problem is related to the fact that the base64 alphabet is not URL-safe. In this particular case, your base64-encoded string contains a +, which is interpreted as a space.
To solve this, you can either:
Use a URL-safe version of the base64 alphabet, i.e. replacing + with -, / with _, and trimming the trailing = paddding, as described in RFC4648. This answer includes a code sample for this approach.
URL-encode your content after base64 encoding, turning + into %2B, / into %2F, and = into %3D.
This should solve your problem, but it goes without saying that in an untrusted environment, giving users the ability to inject raw HTML into your site constitutes a serious security risk.

How to decode string with mixed content (Latin & UTF-8) in PHP

I have a PHP script that read emails/usenet messages, I found a case where I have a text that's a mix of arabic & latin words, ie.
PHP and ARABIC_WORD
ie.
PHP and الساعة
The problem is, the text is encoded, ie.
Some Text =?utf-8?b?RVByaW50cyBhbmQg2KfZhNi52LHYqNmK2Kk=?=
My question is How can I decode this ?utf-8?... when it's mixed with latin text?
I'm using PHP 5.4.15
What you've got is the MIME Encoded-Word syntax used in email messages for non US-ASCII encoded texts:
The form is: "=?charset?encoding?encoded text?=".
charset may be any character set registered with IANA. Typically it would be the same charset as the message body.
encoding can be either "Q" denoting Q-encoding that is similar to the quoted-printable encoding, or "B" denoting base64 encoding.
encoded text is the Q-encoded or base64-encoded text.
-An encoded-word may not be more than 75 characters long, including charset, encoding, encoded text, and delimiters. If it is desirable to encode more text than will fit in an encoded-word of 75 characters, multiple encoded-words (separated by CRLFSP) may be used.
So this little excerpt from wikipedia also contains how you can decode the string. Sure you're not the first one who needs to do this, therefore libraries exist. See as well:
Best way to handle email parsing/decoding in PHP?
proper way to decode incoming email subject (utf 8)
it seems to be encoded text: try with php function base64_decode.
$my_string = 'test string';
$res = base64_encode($my_string);
echo $res; //dGVzdCBzdHJpbmc=
echo base64_decode($res); // test string
in fact, decoding your string:
base64_decode("RVByaW50cyBhbmQg2KfZhNi52LHYqNmK2Kk=")
return something like this:
EPrints and العربية

Encryption string on Codeigniter

just wanted to verify if on Codeigniter Encryption say like this one
hhNa0fUcOc3k0jUhPcRBJshpiXLpUSug+NhgPk89O7eSjerHk6go360U9rl8LazZo6DR6M1N4IqG0PYIwPyKhQ==
Is the structure of this string always have a '+', '=' and a '/' character?. Just wanted to verify things before i parse them. Is there a case wherein when a string is encrypted it may contain special character other than '+, =, /' signs? Just a heads up, i didn't used any mcrypt thing other than the default specified on CI.
This seems like a base-64 encoded string. + and / are valid characters, and = are padding which will always show up on the end. +, / and = are the only special characters in a standard base-64 implementation.
use this to remove = from the encoded string while using base64_encode
<?php echo rtrim(base64_encode($content_string),'=') ?>

Hashing JSON in PHP does not produce the same result as in Javascript for unicode characters

My web application communicates with the server over JSON protocol. Before sending each JSON message from the web application, I run a hmac-sha1 function on it (on already encoded object) and insert the resulting HMAC into the header of JSON request.
On server side, I decode JSON message with PHP, extract the HMAC, unset() the HMAC from the object and then encode the object back into JSON and create a HMAC of it.
The HMACs match as long as I don't use characters like "ž, š, č". When I use those characters in the message, the HMACs don't match anymore.
In the web application I'm using jQuery.post() to transmit the already encoded JSON string.
If I send the data I got from the web application back to it in the JSON encoded reply, the application will display "ž, č, š" just nicely.
How can I make the HMACs match?
UPDATE:
This is only a problem on latest version of Firefox and Opera. It works fine on IE8 and Chrome. On the former browsers, the JSON string (before it is sent) is:
{"body":[{"name":"Žiga Kraljevič","email":"test#email.com","password":"secretpass"}],"header":{"apiID":"person-27jhfa83ha-js84sjj18dasjd","hmac":"e4259d6ef8f477c020d644409cc16dd9c42301e8"}}
While on the latter browsers (IE8 and Chrome, where it works) is the following:
{"body":[{"name":"\u017diga Kraljevi\u010d","email":"test#email.com","password":"secretpass"}],"header":{"apiID":"person-27jhfa83ha-js84sjj18dasjd","hmac":"e4e9e2d0d8d11728a2b4329ad6dacdb9409b1de1"}}
You're probably running into multiple issues. One of them may well be that the character encoding being used on the client is different from that being used on the server, worth ensuring that they're the same (more about character encoding in Joel's excellent essay). Another may well be that there are multiple correct ways to encode things. The encoders may well be using different ways. For instance, you can encode a " within a string as either \" or \u0022. Both are valid, and they're equivalent, but the hashes won't match. Similarly, I'm a bit surprised you're not running into more trouble when not using accented characters, for instance with whitespace.
What is your hmac-sha1 function, where's it from? If it is taking a JSON String as input then there's an implicit encode-to-bytes step going on here because SHA1 operates on bytes, not UTF-16 code units like JS String.
I would suspect that your JS function is using a “one code unit n per byte n” type of encoding, for easy calculation with tools like getCharCodeAt. This is effectively the same as if the character string input had been encoded to ISO-8859-1. Whereas if you are using encodeURIComponent or posting the raw characters via XMLHttpRequest, the implicit encoding there is UTF-8.
You could convert the String to UTF-8-bytes-stored-as-code-units format for the JS hmac-sha1 function, that might make it match PHP. There's a sneaky idiom to do this:
var utf8= unescape(encodeURIComponent(s));
When POSTing JSON I base64 and urlencode it anyway
URL-encoding should be enough (with encodeURIComponent, not escape which is the wrong thing for absolutely everything except the reverse step of the UTF-8-conversion trick above).
BTW, what's the purpose of this? You do know it doesn't in any way secure the connection between the browser and the server, yeah?
Edit:
I'm using jssha.sourceforge.net for sha1-hmac. In PHP I'm using hash_hmac.
Works for me:
var data= '\u017E, \u010D, \u0161'; // 'ž, č, š' in a Unucode string
var utf8bytes= unescape(encodeURIComponent(data));
var hmac= new jsSHA(utf8bytes).getHMAC('foo', 'ASCII', 'SHA-1', 'HEX');
alert(hmac); // 5d15f0b9...
var form= 'message='+encodeURIComponent(data)+'&hmac='+encodeURIComponent(hmac);
xmlhttprequest.send(form);
...
$utf8bytes= $_POST['message']; // "\xc5\xbe, \xc4\x8d, \xc5\xa1"
// which is 'ž, č, š' as UTF-8 in byte string
$hmac= hash_hmac('sha1', $utf8bytes, 'foo');
echo $hmac; // 5d15f0b9...
echo strtolower($hmac)===strtolower($_POST['hmac']); // true
This uses the binary ('ASCII' to jsSHA) key foo. If you are using a binary key with non-ASCII characters in it, you would have to make sure that those are properly encoded too, in the same way as the data.
The key for HMAC is a shared secret between the server and the client, which has been previously exchanged over a secure connection.
It's not only the key you'd have to send over a secure connection, but the entire page and all scripts in it. Otherwise a man in the middle attack could sabotage your scripts on the way to the browser to replace them with a version that used the secret key to sign bogus messages. If you've got an HTTPS server for all this stuff, fine. I'm not sure what the HMAC would be doing in that case though, it seems a bit involved for an anti-XSRF scheme.

Categories