norwald2
norwald2

Reputation: 131

Easy Encryption and Decryption with PHP

My PHP Application uses URLs like these:

http://domain.com/userid/120
http://domain.com/userid/121

The keys and the end of the URL are basically the primary key of the MySQL database table.

I don't want this increasing number to be public and I also don't want that someone will be able to crawl the user profiles just by interating the Id.

So I want to encrypt this Id for display in a way I can easily decrypt it again. The string shouldn't get much longer.

What's the best encryption method for this?

Upvotes: 8

Views: 6458

Answers (9)

Vikram Nain
Vikram Nain

Reputation: 1

When user click on a link you should not use primary key, You can use the pkey in a session and get it from that session. Please do not use query string....

Upvotes: 0

marcusklaas
marcusklaas

Reputation: 492

I'd probably say it's better indeed to just create a random string for each user and store that in your database than to get one using hash. If you use a common hash, it's still very easy to iterate over all pages ;-)

I would write this in comments, but don't have the rep for it (yet?).

Upvotes: 0

Victor Nicollet
Victor Nicollet

Reputation: 24577

You have a variety of choices here:

  • Generate and store an identifier in the database. It's good because you can then have readable keys that are guaranteed to be unique. It's bad because it causes a database schema change, and you have to actually query that table every time you want to generate a link.

  • Run an actual key-based encryption, for instance based on PHP's MCrypt. You have access to powerful cryptographic algorithms, but most secure algorithms tend to output strings that are much longer than what you expect. XOR does what you want, but it does not prevent accessing sequential values (and the key is pretty simple to determine, given the a priori knowledge about the numbers).

  • Run a hash-based verification: instead of using 121 as your identifier, use 121-a34df6 where a34df6 are the first six characters of the md5 (or other HMAC) of 121 and a secret key. Instead of decoding, you extract the 121 and recompute the six characters, to see if they match what the user sent. This does not hide the 121 (it's still right there before the hyphen) but without knowing the secret key, the visitor will not be able to generate the six characters to actually view the document numbered 121.

  • Use XOR with shuffling: shuffle the bits in the 30-bit identifier, then apply the XOR. This makes the XOR harder to identify because the shuffle pattern is also hidden.

  • Use XOR with on-demand keys: use fb37cde4-37b3 as your key, where the first part is the XOR of 121 and md5('37b3'.SECRET) (or another way of generating an XOR key based on 37b3 and a secret).

Don't use base64, it's easy to reverse engineer: if MTIx is 121, then MTIy is 122 ...

Ultimately, you will have to accept that your solution will not be secure: not only is it possible for users to leak valid urls (through their browser history, HTTP referer, or posting them on Twitter), but your requirement that the identifier fits in a small number of characters means a brute-force attack is possible (and becomes easier as you start having more documents).

Upvotes: 4

Chandresh M
Chandresh M

Reputation: 3828

you can use base64_encode and base64_decode function for encrypt and decrypt your URLS

Upvotes: -1

hmassad
hmassad

Reputation: 19

Simplest but powerful encryption method: XOR with a secret Key. http://en.wikipedia.org/wiki/XOR_cipher No practical performance degradation.

Base64 representation is not an encryption! It's another way to say the same.

Hope this helps.

Upvotes: 1

shamittomar
shamittomar

Reputation: 46692

Simple Obscuring: Base64 encode them using base64_encode.
Now, your http://domain.com/userid/121 becomes: http://domain.com/userid/MTIx
Want more, do it again, add some letters around it.

Tough Obscuring: Use any encryption method using MCrypt library.

Upvotes: 7

user187291
user187291

Reputation: 53940

generate an unique string for each user and use it in your urls

http://domain.com/user/ofisdoifsdlfkjsdlfkj instead of http://domain.com/userid/121

Upvotes: -1

John Parker
John Parker

Reputation: 54415

A better approach (from a usability and SEO perspective) would be to use a unique phrase rather than an obscured ID. In this instance the user's user name would seem an ideal solution, and would also be un-guessable.

That said, if you don't want to use this approach you could just use a hash (perhaps md5) of the user's user name which you'd store in the database along with their other details. As such, you can just do a direct lookup on that field. (i.e.: Having encrypt and decrypt part of the URL is probably overkill.)

Upvotes: 6

jwueller
jwueller

Reputation: 30996

Obscuring the URL will never secure it. It makes it harder to read, but not much harder to manipulate. You could use a hexadecimal number representation or something like that to obscure it. Those who can read hex can change your URL in a few seconds, anyway:

$hexId = dechex($id); // to hex
$id = hexdec($hexId); // from hex

Upvotes: 0

Related Questions