I have a weird question,
Is it possible to encrypt mssql sp or triggers or even queries? like in php base64 system.
If it's possible, can someone provide me a link of the method or a small tutorial explaining how to use the encrypted method to be read from sql?!
all I want is a small encryption method that allows me to encrypt my queries and let the sql read it over the encryption itself. just like php
If I understand correctly you want encryption to happen in SQL itself. I would suggest against this as it kind of defeats the whole purpose of encrypting the data. The reason behind it is usually that if a 3rd party gains access to your database (and not application code), they still cannot read the data. If you set encryption to happen in SQL, then they will be able to decrypt the data.
If this is not what you've wanted, then sorry for my wasted reply.
Related
I have been asked to do some research on how form submission data can be encrypted and ensure that it is stored securely in a database. The form submission will contain personal details about employees and these must be kept secure.
I have come across AES_ENCRYPT() during my research and have managed to apply this function so that it stores the data successfully in the database.
Example SQL statement I used:
"INSERT INTO employee (firstname) VALUES (AES_ENCRYPT('$name', '$encryption_key'))"
However, I have very limited knowledge in this area and am not sure if this is sufficient enough protection to prevent the data being hacked. What level of security does this provide? Is there anything that I have missed or another technique I could use to improve my implementation?
Additionally, I have stored the encryption key in a separate PHP file but I do not know what the recommended way to store it is. Any advice on this would be much appreciated.
Sorry if this question is vague or quite broad. I am a complete beginner in this area. I am happy to provide more information if it is needed.
AES (Rijndael) crypto is pretty doggone secure. In practice, unless your data is tremendously valuable, you can consider it secure. Unless some actor with vast resources decides they want to crack your encryption, nobody will.
But it's symmetric. It uses the same key to encrypt and decrypt stuff. So, you can consider it to be as secure as your key.
Your key is insecure. If a cybercreep cracks the server running your php code, they immediately get access to your key. And that gives them access to your encrypted data. And they have a bright neon road sign saying "here's the data I think is sensitive."
Don't forget that security depends on the weak link. Generally it's considered smarter to use your money and time to secure your server, rather than use symmetric encryption on a few columns of a dbms. In other words, with respect, you're probably wasting your time doing this column based encryption.
If you absolutely must encrypt data at rest, you should consider using an asymmetric (public / private key) cryptosystem. Encrypt stuff using the public key, and keep the private key on an airgapped secure system in case you need to decrypt some data.
Your example (first name) isn't sensitive enough to be worth this trouble.
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
How should 'sensitive' data be stored in MySQL Database?
1) Should I focus more on the security of the MySQL database and store the data as plain text?
I found a step by step tutorial on how to make a MySQL database more secure:
http://www.symantec.com/connect/articles/securing-mysql-step-step
2) Should I encrypt the data?
If yes, then how should the encryption be done?
Using MySQL aes_encrypt/aes_decrypt?
Using PHP AES functions/algorithm for encrypting/decrypting data?
How should the data be stored in MySQL?
BLOB
BINARY
VARBINARY
In my case the 'sensitive' data are payments done by individuals.
Thanks
It's a mixture of both. Two existing answers (at the time I wrote this https://stackoverflow.com/a/10718397/1015483 and https://stackoverflow.com/a/10718459/1015483) are valid - you need to look at about 5 methods of possible attack that I can think of
They get access to your DB server; so yes, secure that baby as much as is reasonable (Matt's answer)
Stand alone data hijacking (someone gets to your database data somehow else, could be a backup, could be they guess a password, could be MITM if you transfer data from one place to another). For this, you do encypt your data. You also may do a CSV dump for some reason and e-mail to someone. Whoops. But it happens. So encrypt (vlzvt's answer)
But three elements not mentioned:
They could gain access to your web server (if different from your DB server). If they have access to the webserver, all bets are off as they have your password, encyption keys the lot. So you need to make that even more secure than the DB server. (Matt might have meant that above - but just make it clear)
Similar to above, but not to be forgotten, is if someone gets access to phpMyAdmin or your management consule. Don't use plain text auth or config stored passwords for access.
Finally there's your application itself (and the hardest to lock down). You need to prevent against SQL injections that may reveal data. Encrypting the data would stop minimise problems if someone did gain access through an untrapped query - so for this, encryption is the solution.
For part 2 of your question:
Using MySQL encrypt/decrypt functions will stop someone who has access to the raw data, but not MITM or SQL injection or even CSV dumps taken for transport.
So, IMO (and it's only my opinion and the way I've done it) is to encrypt with PHP and sned the encrypted data over the wire, as that stops all methods of trapping the data, and a CSV dump will be "scrambled".
If you do that, you may as well use the varbinary / blob types as it stops you accidentally trying to read/edit in phpMyAdmin. Plus potentially saves a few bytes nominally (although this depends on indexes and other stuff - so that alone is not a winning argument).
And now the down side: searching and sorting. Anything you index or search on, if encrypted, will only match the entire, exact, case sensitive string padded to the correct length (normally a search will be case insensitive, and you can do part searches with LIKE). And if you want to ORDER BY then you need the original strings. So bear than in mind when designing the structure.
Hope that helps.
What's the worst possible scenario if an attacker gets access to the plain text data? Given that you have to decrypt data in order to make it useful and you therefore need the encryption key to be somewhere accessible too, any attacker who can get to the DB will likely be able to get to the key as well, unless this is for archiving rather than e.g. a live website. I'd focus on the DB server security, unless you're carting HDDs around full of data which might get lost, but it really depends on why you need to encrypt it.
if you need to secure the data in your possibly hacked database, you can encrypt it
with mcrypt
$key = "mykey";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$data,MCRYPT_MODE_ECB,$key);
after that you can select BLOB,TEXT,MEDIUMTEXT or anything, based on the ~expected data size.
* for VARBINARY/BINARY you might need to pack it first.
The encryption operation has additional cost.
You need evaluate if in your scenario, this additional cost will be a problem, per example, if your data grow to considerable size.
The first frontier to avoid data leaks is a strong data access policy with profiles of access an so on. This has the disadvantage that you will need to manage the mysql and configurate it.
If you want care about the managment of profiles, you can encrypt the data assuming the extra cost in CPU and (depend of encyption algorithm) a extra storage space.
The security of the a system is equals to the security of more weak component, don't focus your effort only in encryptation task, this only give you the sensation of security, if the data can be decrypted, the only thing that the intruder needs is time and bruteforce to break the encryption
I'm working on my first secure shopping site. We're not storing credit card data, so that's not a problem. However, we do have a transaction key and API login key for our payment gateway (authorize.net) that I'd prefer to keep in a database, rather than hard-coding into my php. I don't know that we need tremendous security, but I would rather not store it in plain text. I know about sha, but that's one-way. I need a way to store the value in the database in a semi-secure format, but then be able to "decrypt" it programmatically for use in my function.
An additional caveat to this is that my site is hosted, which means there's a very tight limit to what kind of stuff I can install, so ideally any solution would rely on something that's included with a standard php install.
Can anyone point me in the right direction? I'm very new to securing data.
EDITED TO ADD: I checked with my host and mcrypt is installed. Is this the right direction to look in?
MCrypt can be your friend here. What you do need to take into account, though, is that every publicly available (and useful) encryption method requires a key. If AES encryption or 3DES encryption didn't require a key during the encryption process then breaking the encryption would just be a matter of trying every standard decryption method until you got a meaningful result. Thus, storing the key for your payment gateway incurs the exact same risks as storing the key for your encryption. No matter how many layers of encryption you want to add, at some level there will have to be a key stored in plain text, usually hard-coded into the PHP and often in an included config.php file to make it easy to change in the future.
The only option for securely storing information without the need for a key would be to invent your own encryption method. The security of this method lies solely in the fact that no one knows the means by which you are encrypting the string, so they don't have a step-by-step pattern to just walk backwards through. If you ever told someone how your encryption worked, though, then the security would be forfeit. Also, there are many algorithmic ways to break simple encryptions (letter replacement, for example). This is why mathematicians get a lot of money for developing things like AES.
Your best best is to look into MCrypt Encrypt and MCrypt Decrypt. This way if just your PHP is compromised then they know the key you used to encrypt, but they don't have the data. If just the database is compromised then they have the data but not the key you used to encrypt it. If both are compromised, you're screwed. But if both are compromised you're screwed no matter what you do, so that's a fairly safe route.
Hmm, you can try AES encryption. The problem is that you have to save the salt hash(98sdfx9c6v5c) somewhere in your PHP.
Insert config:
INSERT INTO config (secret_key) VALUES (AES_ENCRYPT('secret api key','98sdfx9c6v5c'));
select config:
SELECT AES_DECRYPT(secret_key,'98sdfx9c6v5c') AS secret_url FROM config
From a security perspective, there's no difference by storing it in the php files or in the database, if someone has access to your php files he has access to the database as well.
working with mcrypt doesn't mean you will have MORE security, (if they can read your php files they can read the key as well) so...
If I were you i'd store the API key in plain text on a file outside the web server directory.
just write good code you should be fine.
Background Information:
I'm part of a team of developers that runs a web application that stores and retrieves HIPAA (medical) data. Recently, the HIPAA guidelines were updated to include a policy that requires that all identifying client information be encrypted when it is "at rest" (stored in the database and not being accessed).
The Initial Problem
The first problem we had to tackle was determining the best way to two-way encrypt the data in a manner that makes the data secure in the event of a breach.
The initial Solution
The quickest solution we came up with was to use mcrypt to encrypt the data before we inserted it into the database.
The New Problem
The application we're developing is quite old (as web applications go) and uses a lot of procedural programming as well as heavy reliance on the mysql_query function to insert, update, retrieve, and delete data. We do not have the time or luxury of translating our code to a database-abstraction-layer. So, the only way to implement this encryption/decryption system is to manually edit all of the CRUD queries to use data that's been encrypted via mcrypt. This is very inefficient and extremely error-prone.
Our Proposed Solution
We decided that the fastest and most effective way to solve our problem is to overwrite the native mysql_query function with one of our own devising. In our new function, we would encrypt/decrypt the data values before sending the query to the server/ returning the resultset.
Where You Folks Come In
Is this the best solution to solving our initial problem?
How do you go about overwriting an existing, core PHP function?
Although you've previously stated you can't/won't translate your code into a database abstraction layer, I believe that would be the ideal solution. Sure, it's a lot more work right now, but it pays off. What you've proposed is a hack, that can (and probably will) lead to errors and headaches in the future.
The next best thing would be to encrypt the whole database, as proposed in the comments. There are solutions out there for transparent encryption in different levels, ie: this or this
Another thing you might want to look into is MySQL's native encryption and decryption functions, which could be used to implement column-level encryption if you're concerned about performance.
While the best solution would be the abstraction layer that the other answers have suggested, you can override existing PHP functions with your own versions with the PECL Runkit extension
Something like:
runkit_function_rename ( 'mysql_query', 'mysql_query_old' );
function mysql_query ( $query , $link_identifier=null ) {
// modify $query here for UPDATE/DELETE statement and any WHERE clause, etc
$newQuery = modifyQuery($query);
if (is_null($link_identifier)) {
$result = mysql_query_old ( $newQuery);
} else {
$result = mysql_query_old ( $newQuery, $link_identifier);
}
// modify $result here for returned data from any SELECT statement
return modifyResult($result);
}
Note: By default, only userspace
functions may be removed, renamed, or
modified. In order to override
internal functions, you must enable
the runkit.internal_override setting
in php.ini.
It's not a solution I'd really recommend. I had to do something similar some years back in java, where it was far easier to extend jdbc; but while parsing the syntax of SQL queries is hard enough, it gets harder still if your queries are using bind variables. Watch out for escaped strings! Watch out for any use of related function like mysql_db_query, just in case they're used alongside mysql_query within the application!
Apologies for shaky typing. My wife has been bouncing our router a few times while I'be been writing this suggestion
I think one way of handling this automatically would be to look into MySQL proxy
and implement encryption through that. I played around with it 2 or so years ago when it was in a very early stages, and from what I remember it could basically intercept requests and do 'stuff' with them :) No code change required essentially.
Hopefully this helps.
There are commercially available solutions to help with data at rest encryption. You can check out either Gazzang or Packet General. Both offer MySQL encryption to help with HIPPA compliance. Good Luck
You could encrypt at the file system level, and let the OS handle it. If you wish to handle it at the PHP level, extend, don't overwrite.
function mysqle_query() {
// Do some stuff
// like replace fieldnames with AES_ENCRYPT(fieldname) on insert and delete
// and replace fieldnames with AES_DECRYPT(fieldname) on select
mysql_query();
}
I really think you are looking at this from the wrong perspective. This is not a problem to be solved by developers via encrypting/decrypting data as you store and retrieve it from the database - use an infrastructure solution.
Consider hardware or software whole disk encryption, encryption of the database itself via the RDBMS's transparent data encryption function (if the particular RDBMS has one), or via the OS.
See this document from NIST