I'm writing a php application that accepts sensitive customer data, and so I need to encrypt it before storing it in a mysql database. I'm going to use mysql's built-in AES functionality to do column-level encryption.
I want to avoid storing the encryption key on the server, and so i'm going to provide a web-page for an administrator to log-in, and enter the encryption key. I want to store this key in memory while the application is running, but never permanently to disk.
What is the best way to do this?
Can I modify the $_SERVER array to store information between requests? Can I store the key with apache in some way? Maybe shared memory?
Rather than rely on MySQL AES for encryption, why not use PHP's native openssl encryption scheme (a PECL extension). This requires a private and public key, public to encrypt, private to decrypt, and the keys can be kept in separate places.
I ended up storing the encryption key in an in-memory table. All access to the database is done through a set of stored procedures; The stored procedures include the ability to do key management (i.e. insert key to memory-table, change keys, check if a key has been entered etc.), as well as store/retrieve application data.
With this design, the database credentials left on the application server only have the authorization to query through the set of defined procedures, and have no way to read the encryption key directly.
I liked this approach because:
The key isn't stored on the file system - preventing issues with hardware disposal at end-of-life, and from prying eyes of system administrators
The application code can't get access to the key (other than while entering it), so the only place it will ever reside is within the database process.
All logic for encryption/decryption is embedded within the SQL queries, so don't need to worry about application code doing it correctly - Nice for maintenance.
One possibility is to create a RAM disk and store the key there.
The safest place to store any kind of encryption key is on the server NOT in the database, and make sure it is owned by root and not readable by others.
Write a php config file and store it in your home directory. Allow only php to have access to it.
$cryptKey = "aac1ebadcfabdef72376acd" ;
Include at the top of every php page that uses the encryption key using an absolute path to the home folder. This folder is not accessible to the end user.
Related
I'm currently upgrading the security on one of the platforms I seal with. But, I am unable to crack how to securely store my encryption/decryption key.
Current setup:
MySQL server
Webserver
I need to store and read all sensitive data in the database using AES_ENCRYPT/AES_DECRYPT. But, the key for which the data is encrypted/decrypted I would like to store securely. So, in the case where someone gains access to the database or the webserver, they won't be able easily guess the key combination or read it out of a config file.
The key can change depending on the data I need to read/write.
Is this at all possible? First option I thought of was just to use a key combination based on some columns on the data I needed to read. But, that makes it possible to guess by looking at the code if someone was to get hold of both source code & database.
Any thoughts?
An easy and secure way to store your keys is by using a key management service like AWS KMS.
They (should) store keys on FIPS-140-2 validated hardware security modules which are designed for key storing and loading.
Online key management services do that in bulk and provide an api to use your key.
They are the industry standard and should be used to store keys securely since storing them in files or in the database can be secure but doesn't garantuee it.
I'm writing a content delivery system, which saves data on other companies ftp-server. For that I have to store the connection infos, like host, username, password, … in a database.
I will hash the data and thinking about to save the salts in a config file out of root. But I don't like the idea to write the data to a file.
Is there any better solution to save the salts?
You can try doing it by ssh keys. Client company will generate a pair of keys and upload their public key into your system. Your system can - then - use this public key to establish connection and do it's job.
This way it is easy for them to disable such public key (without changing passwords in all of their related systems). They can set public keys to expire in certain time, and so on. They (clients) should feel more safely about that.
You can store public keys in database, or in files, but using database approach should be easier to protect those keys. Any way... That's your responsibility to protect your database. And that's - how to do it - a totally different question :)
I'm sure you can find information about authenticating using ssh keys for any php framework, and in raw php you can also do it using: ssh2_auth_pubkey_file for example.
I am using MySQL as a back end storage.
I was asked by our risk management team to encrypt all the data prior storing it into the database.
Since then I have been doing research on how to secure the data going in and out the database.
I found couple ways one of them was MySQL Encryption Software
A second solution was to encrypt and decrypt data in MySQL using AES_ENCRYPT() AND AES_DECRYPT(). But I will need to create a 128,196 or 256 bit key in order to be able to encrypt and decrypt the data. Then every time I want to execute INSERT/UPDATE I will call AES_ENCRYPT() and supply it with a key to encrypt the data. Then when I execute SELECT then I will have to call AES_DECRYPT() and supply the same key to convert the data to a plain text.
This means that I will have to define a variable in my PHP script that have the private key so I can encrypt/decrypt by supplying the defined variable to both AES_ENCRYPT() and AES_DECRYPT()
My question is
Where/How to a store this private key to prevent a hacker from reading it. if someone hacks my server reads the key then he can simply read the data and the encryption would be mean less.
And what is the best way to go about securing my data?
Thank you
The issue you are facing is not a key issue but an issue of security of the rest of your computer. Using mysql means that mysql (if running safely) is running in it's own account. You would in fact put the keys in your mysql-owned directory. That secures much of mysql. MySql itself needs to have access to that key, so there is not much more you can do for that account. Just make sure it is readable only by the owning account.
If you hide your key and the hacker gets to your PHP code the hacker could do the following:
A. Echo/Print the KEY (it's a variable). He doesn't have to find the code where you define it, he could look for the function where you use it.
B. Forget about the KEY and use your own decrypting function to see the data and export it.
Most of the hacks are exploits to your PHP code, you should secure your computer, system and database.
Use MYSQL Stored Procedures
If only an authenticated user can get the key you could do this... Hide the KEY in a MYSQL STORED PROCEDURE and only give the key to the user when he completes the log in. All the data in the database should be encrypted and the key is not accesible as plain stored data. It should be inside the SQL Stored Procedure that a user having a password will get as query result. Users table should not be encrypted, only the password as one way.
This last solution should work only for authenticated users, like apps as example. You could protect the user profiles easily with this solution.
Users (basic data) --> Profiles (all personal details that depend upon log in)
I don't know much about stored procedures, but for sure you could apply it to the entire database and make your data accesible only through them.
Look at this article:
http://www.sitepoint.com/stored-procedures-mysql-php/
And you will find PROS and CONS here:
http://code.tutsplus.com/articles/an-introduction-to-stored-procedures-in-mysql-5--net-17843
I have a website that users submit sensitive data to it then a php script encrypts these sensitive data using rijndael 256 and store it in mysql database
the problem is that I want to store the key in a secure place that can be accessed only by the php script and not to be seen by any other one
Depends on how high a security you need for the data. You could consider having a different security key for each user, by possibly encrypting the data that identifies that particular customer and attaching it onto the 256-bit encrypted key. But better still would be split the key up and insert that encrypted data throughout the key. Makes it more complex to decipher. This would mean if a programmer has access to the key the programmer can't simply decrypt everyones data without having access to the customer encrypted data as well which would be different for every user.
And yes it is true that the programmer can still echo the key out to the screen but they would ALSO need the customer encrypted data for each customer they want to decrypt the data of.
You could also consider Public and Private Key Encryption instead if applicable. The customer/user could generate their own keys. Customer places the public key into a form on the website which gets stored in the database, then the customer/user would have the private key to decrypt the data. You use the public key to encrypt the data. This would mean each user/customer would have their own set of keys. The Private key could possibly be even placed on a keycard and hooked to the computer to verify access.
More information # http://en.wikipedia.org/wiki/Public-key_cryptography
One alternative would be to have the PHP script call an external script (doesn't necessarily have to be another PHP script; it could be anything) that would have access to the key. As long as no one has write access to the external script, or read access to it if you hard-code the key into it, then it should be relatively secure. If you store the key in a separate file, that file needs to be readable/writable only by the owner of the external script.
You could encrypt/decrypt with certificates and have the server request a password for the certificate upon bootup.
The good thing is that your key is only in memory and can be different for every installation/server.
However, this method is quite a pain and generally only works when you have your own system administrators/are not dependent on a third-party hosting provider.
The intermediate solution to generate an encryption key per section/user/client in your database and encrypt the sensitive data with this per client key. These per-client keys are encrypted with a master key and stored in your database, while the master-key is stored somewhere in on disk with minimal priviliges.
This will not safe you when your server gets fully compromised, but does limit the risk in case of -for example- a data-leak/partial compromise.
If the problem is you don't trust a) the programmer or b) the system administrator, you are out of luck.
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.