I'm new to this encryption thing, so i'm not realy sure how to format my question.
Anyways i'm using framework called kohana and for encryption it uses three things:
key, cipher, mode so my problem is that when it encodes some string sometimes i get / in encryption like this fclzSev6DVfOk2Z/BSSi4dRYFn4t and i don't want that so my guess is that i should change mode which right now is MCRYPT_MODE_NOFB so if i'm right what mode do i have to use?
As Francis Avila notes, the encrypted output seems to be Base64-encoded, and so may contain slashes and plus signs (and possibly equals signs at the end) in addition to letters and numbers.
You can safely replace those signs with something else, as long as you remember to change them back before decoding. The PHP strtr() function is handy for this. For example, here's how to convert a string from normal Base64 to the RFC 4648 URL-safe Base64 variant and back:
$url_safe_base64 = strtr( $base64_string, "+/", "-_" );
$base64_string = strtr( $url_safe_base64, "-_", "+/" );
mode has absolutely nothing to do with whether the generated output has slashes, but specifies what mode of encryption mcrypt should use. If you don't know what it's for use the default.
The reason there are slashes is that Kohana's encode() method will encode the binary output from the encryption in base64, which may contain slashes.
You can str_replace() the slashes with something else, but this will probably create more problems and headaches than it solves.
Related
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)));
While finishing my websites java login program and page, I decided to pass an encypted value through the URL to a validation page as an extra line of security. I have an encyrption algorithim that I wrote long ago that no one I know has cracked yet so I want to use that. But I need chars for it to properly work. From what I can tell, PHP doesn't have a char type. So my question is first, is their a char type, and secondly, is it possible to convert that to an int? Side Note: Login is a signed applet so all pages are in PHP. Edit: Forgot to mention that this is just the base of encryption and I will be adding to the algorithim.
You can reference a character in a string $str by $str[$index].
The ord function will return a character's integer value:
$val = ord($str[$index]);
The chr function does the opposite:
$char = chr($val);//$char == $str[$index]
You can access a string $s character by character by referring to $s[$i]. ord($s) gets the ASCII value of a character, chr($n) gets the character corresponding to an ASCII value.
Don't use your own cryptographic primitives unless you know what you are doing! Use PHP's own implementations of known strong algorithms (e.g. AES-256). Just because no one you know has cracked your custom algorithm doesn't mean someone else can't.
There is no char type in PHP, and the string type does not readily convert to int. PHP handles dynamic type-juggling, so type declarations are not used.
On a side note, "no one has cracked [my encryption algorithm] yet" doesn't necessarily mean someone won't in the future. If you're encrypting important stuff, use the standard encryption algorithms - they're standard for a reason.
I need to encrypt a string using MySQL's AES_ENCRYPT function, then attach that encrypted string to the end of a URL, such that it can then be decrypted and used by a PHP script on the other end.
Basically, I am encrypting the string (using MySQL's AES_ENCRYPT), I am then using PHP's rawurlencode() function to make it "URL safe". I then pass the encrypted string in a URL, which is then retrieved by the PHP script on the other end where it gets successfully decrypted... about 95% of the time.
Seems as though about 5% of strings are encrypting in such a way that they are getting corrupted somewhere in the process, and can't be decoded on the other end after being passed by a URL. Can anyone help me out here? Is there a 100% fool-proof way to do this? I have also tried using urlencode() as well as base64_encode() in varying combinations.
Thanks.
Solved.
Once I have encrypted the string using MySQL's AES_ENCRYPT function, I use PHP's bin2hex() function to convert that encrypted data (which is in binary form) in to Hexidecimal. I then pass the Hexidecimal as a string on the end of the URL. Once the URL is received on the other end, I then use this custom PHP function to revert the Hex string back to binary:
function hex2bin($data) {
$len = strlen($data);
return pack("H" . $len, $data);
}
From there, all that's left to do is decrypt the data using MySQL's AES_DECRYPT function, and wha-la. The original string is successfully restored.
URLs have a finite maximum length. AES-encrypted strings do not.
URLs are not an appropriate vector for passing arbitrary information. Using an HTTP POST is a much better way, if you must communicate over HTTP.
About why you are having problems: quoting from the PHP manual page on urlencode:
Note: Be careful about variables that
may match HTML entities. Things like
&, © and £ are parsed by
the browser and the actual entity is
used instead of the desired variable
name. This is an obvious hassle that
the W3C has been telling people about
for years. The reference is here:
http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.2.
PHP supports changing the argument
separator to the W3C-suggested
semi-colon through the arg_separator
.ini directive. Unfortunately most
user agents do not send form data in
this semi-colon separated format. A
more portable way around this is to
use & instead of & as the
separator. You don't need to change
PHP's arg_separator for this. Leave it
as &, but simply encode your URLs
using htmlentities() or
htmlspecialchars().
In looking at URL safe base 64 encoding, I've found it to be a very non-standard thing. Despite the copious number of built in functions that PHP has, there isn't one for URL safe base 64 encoding. On the manual page for base64_encode(), most of the comments suggest using that function, wrapped with strtr():
function base64_url_encode($input)
{
return strtr(base64_encode($input), '+/=', '-_,');
}
The only Perl module I could find in this area is MIME::Base64::URLSafe (source), which performs the following replacement internally:
sub encode ($) {
my $data = encode_base64($_[0], '');
$data =~ tr|+/=|\-_|d;
return $data;
}
Unlike the PHP function above, this Perl version drops the '=' (equals) character entirely, rather than replacing it with ',' (comma) as PHP does. Equals is a padding character, so the Perl module replaces them as needed upon decode, but this difference makes the two implementations incompatible.
Finally, the Python function urlsafe_b64encode(s) keeps the '=' padding around, prompting someone to put up this function to remove the padding which shows prominently in Google results for 'python base64 url safe':
from base64 import urlsafe_b64encode, urlsafe_b64decode
def uri_b64encode(s):
return urlsafe_b64encode(s).strip('=')
def uri_b64decode(s):
return urlsafe_b64decode(s + '=' * (4 - len(s) % 4))
The desire here is to have a string that can be included in a URL without further encoding, hence the ditching or translation of the characters '+', '/', and '='. Since there isn't a defined standard, what is the right way?
There does appear to be a standard, it is RFC 3548, Section 4, Base 64 Encoding with URL and Filename Safe Alphabet:
This encoding is technically identical
to the previous one, except for the
62:nd and 63:rd alphabet character, as
indicated in table 2.
+ and / should be replaced by - (minus) and _ (understrike) respectively. Any incompatible libraries should be wrapped so they conform to RFC 3548.
Note that this requires that you URL encode the (pad) = characters, but I prefer that over URL encoding the + and / characters from the standard base64 alphabet.
I don't think there is right or wrong. But most popular encoding is
'+/=' => '-_.'
This is widely used by Google, Yahoo (they call it Y64). The most url-safe version of encoders I used on Java, Ruby supports this character set.
I'd suggest running the output of base64_encode through urlencode. For example:
function base64_encode_url( $str )
{
return urlencode( base64_encode( $str ) );
}
If you're asking about the correct way, I'd go with proper URL-encoding as opposed to arbitrary replacement of characters. First base64-encode your data, then further encode special characters like "=" with proper URL-encoding (i.e. %<code>).
Why don't you try wrapping it in a urlencode()? Documentation here.
How to safely encode PHP string into alphanumeric only string?
E.g. "Hey123 & 5" could become "ed9e0333" or may be something better looking
It's not about stripping characters, its about encoding.
The goal is to make any string after this encoding suitable for css id string (alnum),
but later I will need to decode it back and get the original string.
bin2hex seems to fit the bill (although not as compact as some other encodings). Also take care that CSS ids cannot start with a number, so to be sure you'll need to prefix something to the bin2hex result before you have your final ID.
For the reverse (decoding), there's no such thing as hex2bin, but someone on the PHP documentation site suggested this (untested):
$bin_str = pack("H*" , $hex_str);
You can use BASE64 encoding
http://php.net/manual/function.base64-encode.php
This thread is dead for long time, but I was looking for solution to this problem and found this thread, someone might find the easy answer useful.
My solution is:
str_replace('=', '_', base64_encode($data));