I need to implement a simple (not ultra-secure) but fast file en/decryption using PHP, so files are encrypted on upload and decrypted on download. Files are mainly images (jpg) and videos (mp4), and some videos are up to 30 MB, so my idea is to encrypt only the first X bytes of each file, just to avoid anyone that could have access to the server (ie. support people) to open the files from users.
I am new to this subject and after almost 6 hours researching found only old examples, using deprecated Mcrypt.
Please, can anyone give me tips to start? Is there any native method from PHP that I can use, or maybe an open-source library? Does Mcrypt would be an option, even if deprecated (I am using PHP 5.6). Do you think encrypting only the first X bytes of the file is a good approach in my case?
Thanks!
Here is a PHP encryption library: https://github.com/defuse/php-encryption
I found this just by googling, I can't vouch for it's reliability or security. There are documentation and examples on that page.
However I really would ask you to take a step back and consider what the purpose of this is and what the wider security considerations are. In order to do this successfully then there will need to be some security secret, either a key or a password, that will need to be kept hidden from the people that you don't want to be able to decipher the data. I can imagine that would be difficult if those people are the support staff. If you made the password the users login password you are setting yourself up for widespread data loss when a user forgets their password. Also at some point it will need to be unencrypted and you will need to think about making sure that is not leaked at this point. And then you need to think about who has access to the source code that handles the file access, and the key/password code. What about server logs and caches? Etc etc
Furthermore if you are only encrypting the first X number of bytes and don't need to make it 'ultra-secure' then I wonder why you are attempting to do it this way at all? I'm not sure what problem it is you are trying to solve.
Given that doing encryption properly is not simple (not to mention costly in terms of computing resources), but if you don't do it properly it isn't much good then I can't help suspect you will probably be much better off spending the effort making sure that untrusted persons only access information on a need-to-know basis and all access is logged in order to keep people honest.
Related
This may be somewhat of a faugue description of my question, and I am unsure if this is best to be posted on Stackoverflow or on Super User.
My problem is the following, I am in planning stage of building an quiz ios-app. In some cases it would actually hand out physical prizes monthly, which means security must be tight enough to decrease cheating possibilities.
I will build a backend in PHP, on a debian server with Apache and a certified SSL (Rapid-SSL).
My guess is that for every question, it needs to send it back and forth to the server for the server to authenticate the answer, and let the user know if the answer was correct or not. For some cases (the non-price-winning quizzes) I even want to return the correct answer.
My question is, what is the best way of doing this, security wise? Should I encode the data that is being send back and forth, and if so... how and with what (is there some common encoding type which I can use, such as base64 or similar)?
Edit
What I meant was encoding, rather then encryption. I updated the question
Also, for authentication I was thinking of using Facebook OAuth login.
Let me explain this in detail:
a) If you are afraid of a man in the middle attack or modification of your packet before sending to server (or receiving data from server), SSL would stop them.
b) If you want to stop hackers/debuggers/reversers, if they reverse your code and your code submits for example high score in SSL, they can also submit it easily, like this:
https://yoursite.com/submithighscore.php?score=[SCORE]
even you are using https, when hacker revealed the URL, score submission method and HTTP parameters, they can also submit fake results using a simple curl command.
So in this case, you can implement an advanced encryption algorithm, like encrypting data using a known algortihm with some your application specific changes, secure your application from reversing (which is hard a little). It will stop most of hackers/reversers.
If you choose a good key-exchange algorithm and encryption schema, faking it for hackers would be hard, except injecting code or modifying your code. This time you have to take all anti-reversing measures. Even if you use a public-key encryption here without taking anti-reversing measures, hacker could inject a code in your application which will add for example X points to every submission of point, it will not take more than a single assembly instruction.
Anyway, it's hard to have a really really secure system, reversers gone reverse, code-breakers gone try to find out your encryption algorithm and try to break it. But you can also do your best to stop most of hackers.
If you are sending over SSL, the data definitely is already encrypted. Thinking about it, the biggest worry is authentication. Knowing for sure that the user that is submitting a question, is actually that user. For that, I would use simple password authentication. And because everything is over SSL, that should be enough. The biggest worry in that case is malware on the user end.
Is it feasible to allow users to login to my web application (php/mysql) using thumb scanner? USB scanners seems available and not too expensive, but has anyone got experience with it? How to make it work with php so users instead of filling in regular username/password fields would actually be able to login by scanning thumb. Are there any opensource/relatively cheap solutions available? So far I found http://www.m2sys.com/ which looks pretty decent but is a bit expensive, considering I would need to provide initially ~400 users with scanners and all that.
This would be quite a bit less secure than what they're normally used for, though it could be useful.
You would have to write a client-side app that could communicate with the scanner, or some way for the scanner to get the fingerprint data and then pass that to the server.
However, this is where you really want (need) to do some security. You don't want to just send someone's fingerprint across the internet - that's like sending a password in plain text. Now anyone who was listening can tell you the fingerprint data and hey! logon!
A "better" way would be to have a client-side app that reads the scan data, performs some type of fingerprint analysis, then encrypt either that data or a hash and then send that information across the net.
It's probably a lot more difficult to do a secure bio-key authentication in this scenario - there are others in which it's a better fit. User/pass pairs are ubiquitous so that everyone is used to them (and 90% of your users probably use the same pair everywhere they go), and security to keep them confidential is fairly robust and relatively simple. That's what I'd stick with - it's easier for you, and easier (more familiar) for your users.
I've done a bit of web programming (using PHP and MySQL), but nothing too large in scale. I've been thinking about how someone would create a social networking type of site and I've ran into some problems.
How would you safely and securely store passwords in MySQL? What kinds of encryption would you use?
If users were allowed to upload pictures, would it be better to store them in the database or have them uploaded directly to the server?
What open source web applications (such as WordPress) would you recommend I read and study (preferably something simple but well written)?
Anything taught in class or written in books just don't seem to translate well into real production code. They just seem like very basic examples.
Thanks!
Regarding password storage: use one-way salted hashing for security. Here's an article on why.
Store a salted hash. I would personally move away from md5 and using something like sha instead. sha1 + salt will hold out for a while =]
If you store the images as blobs in the db, you'll probably have an easier time in the future backing them up (along w/the db, fetching them, etc). But really, they'll be damn fast on the file system too, but I'd prefer them in the database as I have lots of code that interfaces w/the db and I'm comfortable working in that area. That's up to you.
I'm not sure that wordpress will help you to build a social networking site...but its still good to read other's code. I'd take a look at some books on amazon on architecture just to get your mind thinking large scale. Also, take a look at some design pattern books.
I'd also look into something like the Zend Framework or CakePHP. Cake will probably get you up and running rather fast, but I prefer Zend, as its very powerful and doesn't force you to code a certain style. CakePHP is kinda of like rails for PHP.
You'll also want to get decent at security, both server and client side, watching for stuff like session hijacking, sql injection, xss, brute force attempts, remote includes, uploaded file exploits, etc.
Social sites offer many attack vectors to crackers.
Resources:
http://www.amazon.com/Pro-PHP-Security-Chris-Snyder/dp/1590595084/ref=sr_1_1?
http://www.amazon.com/PHP-Objects-Patterns-Practice-Second/dp/1590599098/ref=sr_1_3?ie=UTF8&s=books&qid=1265662237&sr=1-3ie=UTF8&s=books&qid=1265662204&sr=8-1
http://www.amazon.com/Building-Scalable-Web-Sites-Applications/dp/0596102356/ref=sr_1_1?ie=UTF8&s=books&qid=1265662256&sr=1-1
And your local PHP mailing list / meetup.
For the image storing, I always used to store them on the hard disk, but using a very hard image validation script to make sure the images don't contain malicious code.
I'm also used to apply URL rewriting so users can't find the real path to the images.
Don't you have a strange feeling storing images into databases ? The mysql database can grow very fast, and you will always need a PHP script to show up the images, which means it makes your server slower.
As for the password storage, use salting as the others replied.
Last, for the documentation, I really love to see how Wordpress is structured.
I have spent hours watching it's source code and reading it's documentations. It's just a terribly good example of how to organize any website.
Apply a hash function to the password (such as sha1 or md5). Then add extra "salt" to it by taking like the first 5 characters of md5("social") or something. It's up to you, but this is intended so that if a hacker gains access to your database, he/she won't be able to run your hashed passwords through a rainbow table and get the actual password.
I am running a website that allows users to upload pictures. The pictures are organized in bins (that is, 1,000 pictures per bin) just to keep it organized (and you can only have so many files per folder before you run into problems). The location of the pictures is stored in the database as well as other info (like picture id, file extension, bin location, etc). Another table in the database links the picture ids to a user. Also, the picture's filename once its uploaded is something like
{bin}/{userId}_{pictureId}_{token}_{variant}.{fileExt}
Not sure about web applications, but you should definitely make use of some built-in PHP classes such as the PDO database abstraction layer.
For password storage, I suggest using MD5 with a salt. MD5 is impossible to decrypt, but its possible to crack using rainbow tables. For example: Here is a MD5 lookup site I've coded
I would personally upload them directly to the server, however, you need to make sure only valid image files can be uploaded. Don't want someone uploading a rootshell.
Question 3: I would suggest studying one of the modern Rails-style frameworks (my favorite is Symfony) rather than an app like Wordpress or Gallery. They are both excellent, but they've evolved from simple hacks and aren't necessarily the way I would start anything if I was starting from scratch.
Also, for question 2, I hate binary blobs in databases. Filesystems work great for that.
And question 1: one-way hash, as others have said. Mysql's password() function is probably fine.
All these questions have been answered before.
How would you safely and securely store passwords in MySQL? What kinds of encryption would you use?
See https://stackoverflow.com/search?q=password+hash+database+php
If users were allowed to upload pictures, would it be better to store them in the database or have them uploaded directly to the server?
See https://stackoverflow.com/search?q=store+images+database+php
What open source web applications (such as WordPress) would you recommend I read and study (preferably something simple but well written)?
See https://stackoverflow.com/search?q=social+network+php
You should also take into account that running and managing a social network site is more than just coding it. Are you sure you want to build one from scratch? Consider if you would be equally happy with something like Ning, where everyone can start their own community with no programming whatsoever?
I have some PHP source code that I'm hosting with hosting company XYZ. I'm using a PHP encryption software like Zend Guard or ionCube to protect the source from being viewed by anyone (sysadmin or hacker that hacks the sysadmin).
How easy/hard is it for someone who has full access to the system (like the sysadmin or hacker that hacks the sysadmin) to decrypt the source? I don't know how encryption software work, but I'm assuming they use some key, which would have to stay on the server and is therefore accessible to a sysadmin or a hacker. If you're technically-knowledgeable about the how-to, don't hesitate to offer an explanation in your answer.
Does the use of such source encryption slow down the site? If anyone has first-hand experience or knows from someone that has first-hand experience ;)
I'm interested in the technical aspects of this, how effective encryption is.. and its disadvantages, from those who used them or considered using them
Thanks (all helpful answers/comments are up voted)
Edit: the answers so far seem to be ignoring what I'm trying to understand.. I'm trying to understand the effectiveness of encryption. I don't really have any code that needs protection from the bad guys, the above was just an example, so advice like open source it or hire a lawyer don't really address my technical curiosity.. A+ to anyone who gets the point
Encryption (or encoder) schemes try to hide your code as an encrypted file. Obviously, the code has to be decrypted at execution time, which adds useless overhead.
Some of these also insist that the host system install special routines, which the hosters intensely dislike, because they don't want to set up special configurations just for you. But the bad part is that they contain the seeds of their own undoing: to run on the target host, they must contain the decryption software. So if you use one, you deliver the very decryptor necessary to get at your code. Its only a matter of locating it; once found, your code is completely decryptable and exposed. These simply aren't safe.
Obfuscation schemes scramble the names of identifiers, remove comments and formatting. But the obfuscated code runs exactly like the original, with no overhead and no special runtime support needed. Obfuscators depend on the inherent difficulty in understanding programs in general. Programs are hard enough to understand when they are well designed, names are well chosen, and there are good comments in the code. We all hope our programs are well designed, but if the names are bad and the comments are gone, they're pretty hard to understand. Examine your own experience with other people's code.
People will say, "but anybody can inspect obfuscated code and understand it". That's true if you have a tiny application. If your application has any scale (tens of pages of code) it is extremely hard to understand what it is doing when all the variable names are scrambled. The bigger your code, the better obfuscation is at protecting it.
If you want to see examples of what one PHP obfuscator does, see our Thicket PHP Obfuscator.
Neither Zend Guard nor ionCube uses encryption, in it's mathematical sense, to protect your code. What they do, except the obfuscation already described by other answers, is encoding.
This is a process that's normally done automatically by the PHP interpreter each time your script is accessed - your PHP script is compiled into a bytecode format, that's then executed. What encoders like Zend Guard and ionCube essentially does is an equivalent process, only that it's done once, and then only the "compiled" bytecode is made available/uploaded to the server.
This means that actually recreating the very same code that you once wrote is entirely impossible. What is not impossible, and this goes for obfuscation as well, is reverse-engineering the compiled or obfuscated code to figure out what it's doing.
To summarize, I'd say that these products are very good at protecting your code - as opposed to protecting your logic.
Why exactly do you need to encrypt your source code? If you are sporting this as a safe-guard against potential hackers, then please believe when I say that if they really wanted to decrypt your source code, they would do it. It is possible with ionCube, last time I checked.
As far as performance impacts, I believe Zend is a tad bit faster than ionCube due to it not requiring any extra files. But like I said before, don't rely on encryption for anything.
If it can be executed it can be decompiled. Stick to your legal team for rights access, not encryption :) Better yet, open source your project :P
EDIT: 'Encryption' also adds heavily to execution times!
The only thing you can do against the hosting company is to have a good license and lawyer
As far as I know, PHP encoders do not actually encode you PHP code. They just change variable names and add unnecessary rubbish code, so that it becames VERY hard for anyone to find out, what the code does. The problem is that they cannot hide any password (be it the hard coded admin password, or the database connection data).
So they do not ensure that your code is safe, they just make it very hard for anyone to understand it.
I'm going to be implementing a PHP/mySQL setup to store credit card information.
It seems like AES_ENCRYPT/AES_DECRYPT is the way to go,
but I'm still confused on one point:
How do I keep the encryption key secure?
Hardwiring it into my PHP scripts (which will live on the same server as the db) seems like a major security hole.
What's the "best practice" solution here?
You should think long and hard about whether you REALLY need to keep the CC#. If you don't have a great reason, DON'T! Every other week you hear about some company being compromised and CC#'s being stolen. All these companies made a fatal flaw - they kept too much information. Keep the CC# until the transaction clears. After that, delete it.
As far as securing the server, the best course of action is to secure the hardware and use the internal system socket to MySQL, and make sure to block any network access to the MySQL server. Make sure you're using both your system permissions and the MySQL permissions to allow as little access as needed. For some scripts, you might consider write-only authentication. There's really no encryption method that will be foolproof (as you will always need to decrypt, and thus must store the key). This is not to say you shouldn't - you can store your key in one location and if you detect system compromise you can destroy the file and render the data useless.
MySQL, there is six easy steps you can do to secure your sensitive data.
Step 1: Remove wildcards in the grant tables
Step 2: Require the use of secure passwords
Note: Use the MySQL “--secure-auth” option to prevent the use of older, less secure MySQL password formats.
Step 3: Check the permissions of configuration files
Step 4: Encrypt client-server transmissions
Step 5: Disable remote access
Step 6: Actively monitor the MySQL access log
Security Tools
I agree, but don't the cc if you don't need too. But if you really have too, make sure the file that have it is not accessible on the web. You can write a binary that would return the key. This way it's not store in clear text. But if your server is compromise it's still easy to get it.
the security you need depends on your application. for example, if the only time the cc# will be used is when the user is logged in (thin online store type scenario), then you can encrypt the cc# with the a hash of the user's plain-text password, a per-user salt, and a dedicated cc# salt. do not store this value permanently.
since you're not storing this value, the only time you can get this value is when the user enters their password to log in. just make sure you have good session expiration and garbage collection policies in place.
if this situation does not apply to you, please describe your situation in more detail so we can provide a more appropriate answer.
Put your database files outside computer lets say external hdd and keep it at safe place. Works only if you can develop this project at only place where this external drive is placed :)
Or you can at least protect those files using file system encryption tools like
https://itsfoss.com/password-protect-folder-linux/
In case of production environment I agree with Kyle Cronin.