PHP-MYSQL encryption that is safe - php

I'm working on a messagging app, and I would like to encrypt the messages the safest way possible.
Currently I'm doing the following:
chatMessages table
userId | message
---------|---------------------
1 | ENCRYPTED%withChatMasterKey%
2 | ENCRYPTED%withChatMasterKey%
...
chatUsers table
userId | chatMasterKey (it is encrypted aswell with users ID's)
---------|---------------------
1 | ENCRYPTED%withUserId(1)%
2 | ENCRYPTED%withUserId(2)%
...
The messages are encrypted with a random masterKey that are stored in the chatUsers table where with another encryption the masterKey is encrypthed but now the key is the user's Id
So to decrypt the messages, you have to do this in php:
$message = $messagesArray[0]["message"];
$chatMasterKey = decrypt($chatUser[0]["chatMasterKey"], withKey: $userId);
$messageDecoded = decrypt($message, withkey: $chatMasterKey);
Tthat works well, if somebody hacks the dataBase then he would not be able to read out the messages.
But is this safe? If someone hacks the .PHP files aswell, then he will be able to figure out the method I'm using and could be able to decrypt the messages.
Is there a better way to encrypt messages?
/ for security reasons I changed some details in the post /

Related

Storing a long array inside of a MySql Database

I have my database which stores userdata such as username, email, password..
I am currently rewriting the system and trying to improve it/make it more efficient
Currently I need to access an array for a user in the database.
Structure:
username | memberID | email | password | ... |... | skinsInventory |
Now 'skinsInventory is where I want to store this array.
This array could become very big for some users.
Is there a better way to do it or is this the recommended way?
For example some of the users have;
Database skinsInventory
But I can expect this to get quite big.
Any better ways to do this?
Help is very appreciated

Encrypting php-sql user data and structure

I'm working on a online platform that processes financial data and i'm looking to encrypt all data on it, to avoid leaking the information in any way other than the person giving out his personal password. I hope you can help me with this following:
The platform interacts between a php file and a mysql database. A user personal key is defined by a session_id, given after login.
Table 1: Users (user_id, email, password, etc) - this stores the relevant data for any user to logon to our platform and access any of our templates.
Table 2: User_template1_data (template_user_id, user_id, email, name, specific info.) this stores the specific data to the data template
Table 3,4,5,6: logs (log_id, date time, details, template_user_id etc.).
In the log tables (which could be, payments, jobs, 'expanses', etc) we store the sensitive data, that nobody else than the user may read, not even the admins, unless given access to it.
Now the way I had it in mind was following:
Example:
Table 1:
user_id - Name - email - pass
1 - Jay - jay.. - (salt / hashed)
Table 2:
User_template1_data, user_id, division *
1 - 1 - Jay - jay.. - accountant
The php will see that user 1 obviously is an accountant. Which is not really sensitive data.
How ever in Table 3 we add the following data:
> log_id - User_template1_data - date - client - earnings 1 - 1 -
> 2016,01,01 - Gucci SLR - 5000,00 2 - 1 - 2016,02,01 - Prada SLR -
> 51000,00 3 - 1 - 2016,03,01 - Chanel SLR - 15000,00
This connection should be encrypted, so nobody who hacks into the database can see the connections. I was thinking of the following, please correct me if i'm wrong:
> log_id - User_template1_data - date - client - earnings 1 - hash and
> salt the User_template1_data - 2016-01-01 - Gucci SLR - 5000 2 - hash
> and salt the User_template1_data - 2016-02,01 - Prada SLR - 51000 3 -
> hash and salt the User_template1_data - 2016-03-01 - Chanel SLR -
> 15000
This way only the person who is logged in, stores the sensitive data encrpyted, it will not have be be decrypted then.
I AM A ROOKIE TO ENCRYPTING SO PLEASE ADVISE ME IF I'M WRONG
Most importantly, which encryption should i use, how should i build it up etc. Much appreciated!
In general you should set up the database so it can be trusted to be safe, but it could be a fun experiment to solve this. The most important part is using standard encrypt methods in your programming language, in case of php go for the openssl package.
Hash with salt will not help much here, since hashing is a one way operation so not even the user owning the data will be able to decrypt it.
I would have gone for something like
Use an encryption key which you store encrypted with the users password that you decrypt and put in session when the user log in. Of course make sure sessions are encrypted on the disc and that you store the password using bcrypt, but encrypt the key using the clear text password so that the encryption key cannot be found.
When storing sensitive data encrypt it using the key in session and when getting the data decrypt it using the same key
Remember to update the stored encrypted key when the user change password
I suggest using AES-256-CBC for encryption.
If this is going to be used for something more than experimenting or learning I suggest first to search for existing solutions for this.
Also remember if the user forgets the password it will be no way of getting the data back

Storage - Logic/Performance - PHP/MySQL

Okay, here's a standard users table;
Full Name | Birthday | E-Mail | Username | Password | Facebook | MySpace | Twitter | LinkedIn
Nothing unusual about this, it's fairly standard and text book. However, instead of multiple social networking columns for each network it could be stored like so;
Full Name | Birthday | E-Mail | Username | Password | Social
The difference being the information would be stored in the social column as an imploded array rather than in separate columns. It's quite sensible, so if there are into the thousands of users surely it would be quicker to process via script and less hit on the database.
Can anyone think of any DISADVANTAGES of using the suggested method instead of the text book method?
The two disadvantages I can think of:
It will be more difficult to query for social details specific to a certain user. If you knew their Facebook username was fbuser123 then you might have to query for something like SELECT * FROM users WHERE social LIKE '%fbuser123%'.
It will be slightly more difficult to use the information once it's been selected from the database, for example: Requiring that the field be json_decode'ed before it can be used.
Other than that, I can't think of anything else.
I would imagine that if you did this, the most efficient way of storing the data would be in TEXT format and json_encode the data.

Hash id in url php

Logged in user on my site can create documents, pretty much like on Google Docs. The document can be made public by the user, or private (defualt). The documents are stored in a database table like this:
| id | title | content | public | owner |
| 1 | asd | asd | 1 | 1 |
| 2 | asd | asd | 0 | 1 |
| 3 | asd | asd | 0 | 2 |
If public equals 1, it is a public document that can be viewed with a link from any user:
site.com/documents/id
The thing is, even though documents can be public, I don't want users to be able to just increment the url ID by 1 all the time to access all public documents:
site.com/documents/1
site.com/documents/2
site.com/documents/3
And so on...
So maybe I should hash the ID or something like that? Like so:
<?php echo 'site.com/documents/'.md5($id); ?>
Problem is, I can't figure out which ID it is on server side since it is hashed...
What can I do about my problem?
Depending on your security requirements, you should ensure that your document IDs are actually random and not guessable. If you simply hash the auto-incrementing ID, the resulting hash may seem random, but once someone notices that you are simply hashing increasing numeric values (and correctly guesses your hashing algorithm), it is easy to guess possible document IDs.
To achieve this, you could simply hash random numbers (make sure that there are no hash collisions in your database), or work with UUIDs (see this question for an example on how to generate them).
In order to map your hashed identifiers to existing documents, simply store the hash alongside the document in your database (best use the hash as primary key).
You should definitely hash it. Notice that md5 is not secure enough this days, so you may want to take a look at Sha or Blowfish (even if the latter seems an overkill there).
Then you just have to store the hash in the database table that contains the documents properties.
Otherwise you could just create a random hash yourself to identify the document and use that instead of the ID (and obviously check that Murphy doesn't make it so there are two documents with the same hash).
How are you validating that a private document is being viewed by the owner?
While having random ids is certainly helpful in preventing easy guessing of document ids, it seems you're looking at security by obscurity.
In your documents controller you need to check if public == 0 that owner == $logged in user. Within this method you would also verify your unique document id.
MD5 is not ok for hashing numbers, anyone can reverse a numerical md5. I would recommend something a bit stronger, like SHA. (You can also encrypt the entire URL, for more security, as it wont be crackable easily - it wont take up any extra space, as all hashes are the same size regardless of how much data is hashed)
You need to store the hash in the database, and only store it for public files. So any url that has the following URL structure:
"site.com/documents/65hd83jd8h..."
you can lookup in the database, as the hash will be unique.

How do I add "friends" function in PHP?

Hello stack overflow I need help with this problem.
Ok, I have a flat file database in php it records users , hobbies, fav movies and all.
Now i want to add a buddy system so they can have friends and send messages to each other in php without SQL.
Consider having another table (er, flat file?) that maintains links. "Mark" and "John" are buddies if there exists a row in this table (ff?) that links "Mark" and "John". I'd recommend using some sort of index (you know, like a primary key).
Suppose you have a users table (or flat file, whatever, it doesn't matter that much) that contains users and some data, it looks like this:
UID | Username | Hobbies
------------------------
1 | Mark | Swimming, Sailing, Skiing
2 | John | Biking, Paragliding
3 | Suzie | Flying, Skiing
And you have this other friends table (again, flat file, whatever...):
Pair ID | A | B
----------------
1 | 1 | 2
2 | 2 | 3
We've encoded in this friends table that Mark and John are friends, and that John and Suzie are friends, but with the absence of relation 1 and 3, we know that Mark and Suzie are not friends (at least according to our records).
Note that if you want to get all of John's friends, you have to find all rows in your table (or file) that have John's UID (here = 2) in either column A or column B.
Well I am afraid there's no magical answer or a magical PHP function you can call to enable this behavior.
If we are to help you at all we really need some more to work with.
If you really, for mysterious reasons, decide to stick without a SQL database - then I would probably still "tilt" towards a SQL like way of storing it. Assuming you're currently storing each user as a row in a file, with each "field" separated by some character - simply add another "field" in the file and have this containing each "id" of every user that they're friends with (id, being whatever you use for that, could be a name as long as it is unique).
As for the messages, another flat file describing the message itself, sender and recipient would probably be the way to go.
Now the real question is, why so eager to avoid using a SQL database? If it is because of having to install a database, try SQLite

Categories