Here's the story:
I have to pass some classified information from one script to another script. In the first script I need to encrypt the data first and then I have to attach the encrypted data into a GET request and send it to another script. The URL would look like this:
http://mydomain.com/mysecondscript.php?secret={encrypted stuff}
My current encrypt method is based on base64. The problem with this method is, that if I have a lot of stuff to encrypt, the encrypted result could get very long. If it's longer than 255 characters or so, the second script will not be able to decrypt it because the string will be chopped.
So I'm looking for a better encryption method, that can control the length of the encrypted result.
DANGER!
Base64 is NOT a form of encryption, but encoding. Base64 encoded strings are easy to recognize and trivial to decode. Base64 is used to encode data so they can be safely transmitted across non-binary safe medium (such as URLs and emails), but they do not hide the data itself.
What you need to do is encrypt the string using AES (see PHP's mcrypt), then base64 encode it. This of course will not solve your length problem. The question is pretty vague, but what you can do is:
Use POST instead of GET.
Store data in a database or a file which both scripts can access. Then just generate a sort of identifier and send it with the URL. The receiving script can use this identifier to retrieve the data. As an added bonus you won't have to send classified data with the URL.
EDIT: Now that I read your question more carefully, it seems like both scripts are sitting on the same server. In this case there is no reason whatsoever to pass this data via HTTP.
No matter how secure your encryption scheme is you will still need to base64 or URL-encode the result which, you have discovered, will likely exceed 255 characters. The best you can do is compress the data, then encrypt it, then encode it. It will still probably fail. You need to find an alternative to GET.
Why does it have to be transmitted in the URL at all? Save it to disk, put it in the database, add it to a message passing queue...
You can use an opaque token in the URL to identify which thing you're talking about, and then turn that token back into a useful thing on the other end by querying whatever storage mechanism you choose.
If this is sensitive information, base64 should not be used as it can be decoded easily. If you want the information to be securely encrypted, you shoule use PHP Mcrypt (link). Much more secure and can support encryption of much longer strings. Best of all, you set your own key and it cannot be decrypted without that key. It make require a tiny bit more work, but it will be safe. Also, if you are passing multiple variables that way, you can set them into an array, serialize and encrypt the array, pass the array via GET, and then decrypt/unserialize. It's as simple as that. One last thing, there are also some classes out there that will make Mcrypt a lot easier to use. May want to google to find one, it will make your life easier.
You can use MD5 to create a hash of the id so you get something like:
http://www.demo.com/displaycommittees.php?id=81dc9bdb52d04dc20036dbd8313ed055
In your db query you can do a select on the users table including a WHERE statement that also hashes the id column like:
WHERE MD5(id) = $_GET[id]
This works fine and i have always applied this algorithm. for instance assuming the actual value of the encrypted id 23, if you try to put 23 in place of the encrypted(hash) code it will not work( no result will be display).
Note: Reasons are best known to those who need a solution, so the question "why" may not come in for those who need it. they only ask for a solution and if it works fine for them, nice. But for transaction application (e.g cash transaction or transaction pins) please do avoid passing sensitive information via URL, because it can easily be cracked.
See more at: http://softideass.blogspot.com/
Related
I have my own crypt/decrypt function in PHP which is on my server.
I feel it is not a safe thing to store it in my server as if one day we get to be hacked. The hacker can decrypt easily our datas.
Would like to know if is there is solution to this ? How can we protect our own PHP functions ? Is it better to store the decrypt function in another server.
Thank you in advance for your answers !
It looks like you want to disregard Kerckhoffs's principle and that is fine in some cases. If you want to encrypt data at rest, then there is essentially nothing you can do besides obfuscation (PHP code "encryption" techniques are nothing more than clever (?) obfuscation).
For example: Since every obfuscation can be reversed with enough time (but not so much time what would needed to break an encryption), a key that was used to encrypt the data and which is embedded in the code can be extracted and your data decrypted.
If the server only stores encrypted data (which I somehow doubt because that would make it not very useful) and never uses the decryption, only then it would add some security to your arrangement by out sourcing the decryption function. This would raise the bar, because the attacker would need to exploit (possibly other) weaknesses of the second server.
Do Not Implement Your Own Crypto
Never try to develop your own crypto. You should choose use one of tested and trusted by professional. Please watch this video I believe you will understand why you shouldn't implement your own crypto. ( https://www.youtube.com/watch?v=3Re5xlEjC8w#t=49 )
If you really want yo use your own crypto, you may want to encode your php application. Because likely to you are going to store your private key into your source codes.
Example for Plain-text form of PHP source code.
It will be something like when you encode your this php source code.
Further information : http://www.virtual-apps.com/post/security-and-performance-benefits-of-encoding-php-files
the urlencode and urldecode functions are there, but if you have an encoded value that can be easily decoded using the urldecode function.
Is there any other method which can be used to make the query string stronger and less prone to attacks.
using hashing would be fine but if can try not to use too much compute.
It sounds like you're talking about URL strings rather than query strings. The best way to secure variables which you don't want the user to see is to use POST actions instead of GET actions.
The purpose of urlencode is not to provide security, it's to encode strings which may contain special characters etc. to pass in a GET request.
POST does not store the variables as a part of the URL or in the browser history, so it's much better for sending sensitive information. If you want to actually secure the information against user manipulation, you'll have to hash or encrypt it (for example, passwords should be hashed before posting).
POST vs GET comparison
Keep in mind that even using POST, you're not really hiding anything from someone who wants to get at that data. Be very careful of what kind of data you allow to be sent in GET and POST. Know that no matter which you choose, it can still be manipulated by the end user.
Guessing this is what you're wanting to look at. This will show you how to "clean" input from users, whether it's from the query-string or not.
I'm not sure how POST'ing the variables is any safer at all... Chrome Dev Tools will get around that no problem.
I am in the process of building a small web application which will hold around 10 pieces of information for every person inserted. Due to data protection the majority of this information must be encrypted.
Using the CodeIgniter framework and the CodeIgniter encryption class I can encode the information on the application side before storing it in the database. The CodeIgniter encryption class uses PHP's mcrypt function along with the AES_256 cipher.
The problem I have is that I need to allow the users of the application to search the information stored using a wildcard search, Possibly also via an API at a later date.
Any body come across a solution for a similar problem. I've read about the MySQL AES_ENCRYPT and AES_DECRYPT but they still require passing a key back and forth in plain text which I am reluctant to do.
I am currently at the conclusion that if I wish to continue on this route then a full table decryption is my only solution every time a search is made (obviously not good).
Well, you can't search in decrypted text without decoding it first, that is true.
However, that doesn't mean that there are no ways around this. For example, you could make an inverted index of your data and hash (sha1, md5, crc32, pick one) the keys used for searching. All you have to do then is hash the search terms you're using, look them up in the index and retrieve any record that matches, which will only be a small part of the table instead of the entire thing.
By hashing the data (use a salt!), you avoid storing the data in an unsafe way, while you can still search through the data because you made an index for it. No decryption required until you're actually sure which documents match.
I've written a licensing script for some modifications I release freely, and part of my terms and conditions states that upon installation the modification will send the following information for storing in my database:-
Domain Name where the mod is installed
Email address of the site owner
Modification name
Modification version number
All of my modification code is ioncube encrypted, and I'm sending the values through an image URL like so:
http://www.example.com/licenses.php?modname=".$modname."&modversion=".$modversion."&domain=".$domain."&email=".$email."
I'm using an image so that I can return an image to the users browser showing whether a code update is available based on what the user currently has installed.
I'd like to ensure user privacy when sending between domains and send these values encoded, but I'm unsure what encryption is the most appropriate for this situation? I need to be able to decode the values for comparison against the database, but anything that can be decoded by me could easily be decoded by anyone else? What am I missing here? I'm sure others have tried to do this thousands of times before.
Any pointers would be most appreciated.
Don't reinvent the wheel. Use HTTPS/TLS/SSL. If you tell us what web server you're using for the destination, we can point you to setup guides. You may want to use POST in addition. However, it's not really necessary, because TLS will protect the entire query string. A common reason to use POST for secure data is to prevent people accidentally storing data in bookmarks, history, etc., which I don't think applies here.
"I need to be able to decode the values for comparison against the database, but anything that can be decoded by me could easily be decoded by anyone else?"
You can check mcrypt.* and mdecrypt.* which provide symmetric encryption and decryption using libmcrypt (available at the php manual).
you might try to alter your app a bit so that the customer registers on your system and then they get something like an API key which is passed back to you. That way you don't have to pass back their personal information on every request - just pass the anonymous API key.
otherwise you can crypt the data, but people will be able to see your crypt key. you could use public key encryption, of course but that may be tricky to implement
If you have a dedicated server running Apache, you can always rewrite htaccess modules.
This way you can hide Get variables or show to users whatever you want.
#Matthew Flaschen is a viable option too.
I wish to be able to generate URL variables like this:
http://example.com/195yq
http://example.com/195yp
http://example.com/195yg
http://example.com/195yf
The variables will match to a MySQL record set so that I can pull it out. At the time of creation of that record set, I wish to create this key for it.
How can I do this? What is the best way to do this? Are there any existing classes that I can make use of?
Thanks all
Basically, you need a hash function of some sort.
This can be SHA-1 function, an MD5 function (as altCogito), or using other data you have in the record and encoding it.
How many records do you think you will have? Be careful on selecting the solution as a hash function has to be big enough to cover you well, but too big and you create a larger database than you need. I've used SHA-1 and truncate to 64 or 32 bits, depending on need.
Also, look at REST. Consider that the URL may not have to be so mysterious...
This can be done pretty straightforward in a couple of ways:
Use a hash, such as MD5. (would be long)
Base-64 encode a particular ID or piece of data
If you're asking whether or not there is anything that does this already with MySQL records, I'm not sure that you'll find something as design-wise, data is really, really conceptually far away from the URLs in your website, even in frameworks like Grails. Most don't even attempt to wrap up front-end and data-access functionality into a single piece.
In what context will you be using this? Why not just pass post variables? It is far more secure and neat. You will still accomplish the number in the url such as id=195yq, and there is a way to hide them by configuring your php.ini file.
I hope this can be of help to you.
Please keep this in mind. When you pass variables in the address bar it is easy for someone to change the variable, and access information you may not want them to access.
In the examples you gave, it looks like you're base-64 encoding the numeric primary key. That's how I would do it and have done it in the past, but I'm not sure it's any better than passing the ID in the clear because base-64 decoding is trivial.