Re: [PHP] How to store encrypted data and how to store the key?
On 23 June 2010 09:11, Michael Shadle mike...@gmail.com wrote: This is somewhat related to the whole PCI/credit card discussion a couple weeks back. The consensus was basically leave it to other people - however, what if YOU are the other person? I wonder if anyone has some BKMs to share about encrypting data in a web application. A lot of people take the most obvious approach, but it's fundamentally flawed, that is: I take data from the user, I encrypt it (using PHP crypto, or MySQL crypto, etc.) and a key stored in my config file, and put it into the database. Then when I want to get it back, I just use decrypt + the key in my config file. The issue there? If you server is compromised and the database is accessable, they'll have the key to decrypt the data right off the server. They can pull down copies of everything or even write their own script ON the server itself to extract the data. This has been one thing that I have not really been able to figure out yet. You could separate the servers, and figure out some very hard way for them to communicate, but when it comes down to it, the webserver needs to access the data. For example, the webserver could be behind a fully firewalled setup that only allows MySQL traffic. However, the webserver has to access the data still. I assume the only solution is somehow storing the key in a third place, so the accessor has to get the key somehow before accessing the encrypted data. But again - how to automatically allow access for only the webapp? I thought of per-user keys, but that isn't an appropriate solution for something that needs to be encrypted using the same key. Has anyone had to implement anything like this? Is there a good whitepaper on something like this? Especially relating to HIPAA requirements. PCI would be nice too, but I'm sure once this major unknown in my mind is addressed, the general concepts are common, probably just differences in levels of firewalling, cryptography strength, physical access to the machines, etc. Please keep this on topic - this is about the people who DO have to address this issue, not something about just offload it to other guys - that's an obvious choice already, and not one that is allowed depending on the job. I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the app is running. Initialize it by hand whenever the server is started - don't store it on the disk. Yes, your server won't be able to start up the app on it's own but that's the security in the design, not a flaw. If you want automatic access for the web-app you've compromised security (anyone compromising the server has automatic access as well). You're essentially looking at the old problem: if it runs it can be broken. You can only try to make it as hard as possible but there's nothing foolproof. Regards Peter -- hype WWW: http://plphp.dk / http://plind.dk LinkedIn: http://www.linkedin.com/in/plind BeWelcome/Couchsurfing: Fake51 Twitter: http://twitter.com/kafe15 /hype -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] How to store encrypted data and how to store the key?
On Wed, Jun 23, 2010 at 12:21 AM, Peter Lind peter.e.l...@gmail.com wrote: I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the app is running. Initialize it by hand whenever the server is started - don't store it on the disk. Yes, your server won't be able to start up the app on it's own but that's the security in the design, not a flaw. If you want automatic access for the web-app you've compromised security (anyone compromising the server has automatic access as well). That's something I've thought about before. Storing MySQL on an encrypted partition using cryptoloop or something. However, every time the server boots - someone has to manually unlock the partition (unless some sort of physical key is present, then another dimension is introduced) However, that would solve the data being encrypted at rest, more or less. The issue of how to use the data in the web application is still not addressed this way :( -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] How to store encrypted data and how to store the key?
-Original Message- From: Peter Lind [mailto:peter.e.l...@gmail.com] Sent: Wednesday, June 23, 2010 12:22 AM To: Michael Shadle Cc: PHP-General Subject: Re: [PHP] How to store encrypted data and how to store the key? On 23 June 2010 09:11, Michael Shadle mike...@gmail.com wrote: This is somewhat related to the whole PCI/credit card discussion a couple weeks back. The consensus was basically leave it to other people - however, what if YOU are the other person? I wonder if anyone has some BKMs to share about encrypting data in a web application. A lot of people take the most obvious approach, but it's fundamentally flawed, that is: I take data from the user, I encrypt it (using PHP crypto, or MySQL crypto, etc.) and a key stored in my config file, and put it into the database. Then when I want to get it back, I just use decrypt + the key in my config file. The issue there? If you server is compromised and the database is accessable, they'll have the key to decrypt the data right off the server. They can pull down copies of everything or even write their own script ON the server itself to extract the data. This has been one thing that I have not really been able to figure out yet. You could separate the servers, and figure out some very hard way for them to communicate, but when it comes down to it, the webserver needs to access the data. For example, the webserver could be behind a fully firewalled setup that only allows MySQL traffic. However, the webserver has to access the data still. I assume the only solution is somehow storing the key in a third place, so the accessor has to get the key somehow before accessing the encrypted data. But again - how to automatically allow access for only the webapp? I thought of per-user keys, but that isn't an appropriate solution for something that needs to be encrypted using the same key. Has anyone had to implement anything like this? Is there a good whitepaper on something like this? Especially relating to HIPAA requirements. PCI would be nice too, but I'm sure once this major unknown in my mind is addressed, the general concepts are common, probably just differences in levels of firewalling, cryptography strength, physical access to the machines, etc. Please keep this on topic - this is about the people who DO have to address this issue, not something about just offload it to other guys - that's an obvious choice already, and not one that is allowed depending on the job. I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the This is something I'm very interested in hearing more about since our other discussion about PHP threads and how some list members prefer the 'share nothing' approach. That said, how would you access the memory for every individual sessions that need that decrypting code/key when nothing is shared? (I'm assuming that this would be purely in PHP :) Regards, Tommy app is running. Initialize it by hand whenever the server is started - don't store it on the disk. Yes, your server won't be able to start up the app on it's own but that's the security in the design, not a flaw. If you want automatic access for the web-app you've compromised security (anyone compromising the server has automatic access as well). You're essentially looking at the old problem: if it runs it can be broken. You can only try to make it as hard as possible but there's nothing foolproof. Regards Peter -- hype WWW: http://plphp.dk / http://plind.dk LinkedIn: http://www.linkedin.com/in/plind BeWelcome/Couchsurfing: Fake51 Twitter: http://twitter.com/kafe15 /hype -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] How to store encrypted data and how to store the key?
On Wed, Jun 23, 2010 at 12:55 AM, Tommy Pham tommy...@gmail.com wrote: I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the This is something I'm very interested in hearing more about since our other discussion about PHP threads and how some list members prefer the 'share nothing' approach. That said, how would you access the memory for every individual sessions that need that decrypting code/key when nothing is shared? (I'm assuming that this would be purely in PHP :) +1. each server stores it locally in APC, or you have to mess with memcached, and since it is plaintext, encrypt that too? :p I -always- design for 'shared nothing' so this is a necessary discussion too, if in memory is the idea. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] How to store encrypted data and how to store the key?
On 23 June 2010 10:09, Michael Shadle mike...@gmail.com wrote: On Wed, Jun 23, 2010 at 12:55 AM, Tommy Pham tommy...@gmail.com wrote: I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the This is something I'm very interested in hearing more about since our other discussion about PHP threads and how some list members prefer the 'share nothing' approach. That said, how would you access the memory for every individual sessions that need that decrypting code/key when nothing is shared? (I'm assuming that this would be purely in PHP :) +1. each server stores it locally in APC, or you have to mess with memcached, and since it is plaintext, encrypt that too? :p I -always- design for 'shared nothing' so this is a necessary discussion too, if in memory is the idea. In memory means that any of the php processes spawned by the server would have access to it. Encrypting it in memory really doesn't help you, as the php process would then decrypt it, bringing you back to square one: you just mimic the decrypting behaviour of a working php process to get the plaintext key. Shared nothing also doesn't help you - that just multiplies the amount of places the key is placed because you're still facing the same issue: the scripts need access to the key. You could possibly devise an authentication scheme by which a script could authenticate itself to a server that would then hand out the key ... but that's susceptible to other attacks as well. So I'd probably stick the key in memory, possibly memcached. I'd encrypt it but nothing special, just making sure that you cannot get the plaintext from memcached without digging through working php files to figure out how you decrypt it. Then I'd monitor the solution to see if anything *weird* was going on, wiping memcache if something strange comes up. As should be obvious, this doesn't solve the problems. Your number one priority is blocking access to the server. Number two is making sure that noone can use the data *if* they get access but without working scripts. If someone roots the server with everything up and running, there's really very little you can do. This is getting offtopic, though, if memory serves. I believe PCI has some strict requirements on how security should be implemented. You'll have to follow those and not other schemes that may be more or less secure. Regards Peter -- hype WWW: http://plphp.dk / http://plind.dk LinkedIn: http://www.linkedin.com/in/plind BeWelcome/Couchsurfing: Fake51 Twitter: http://twitter.com/kafe15 /hype -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] How to store encrypted data and how to store the key?
On Wed, Jun 23, 2010 at 6:09 AM, Peter Lind peter.e.l...@gmail.com wrote: On 23 June 2010 10:09, Michael Shadle mike...@gmail.com wrote: On Wed, Jun 23, 2010 at 12:55 AM, Tommy Pham tommy...@gmail.com wrote: I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the This is something I'm very interested in hearing more about since our other discussion about PHP threads and how some list members prefer the 'share nothing' approach. That said, how would you access the memory for every individual sessions that need that decrypting code/key when nothing is shared? (I'm assuming that this would be purely in PHP :) +1. each server stores it locally in APC, or you have to mess with memcached, and since it is plaintext, encrypt that too? :p I -always- design for 'shared nothing' so this is a necessary discussion too, if in memory is the idea. In memory means that any of the php processes spawned by the server would have access to it. Encrypting it in memory really doesn't help you, as the php process would then decrypt it, bringing you back to square one: you just mimic the decrypting behaviour of a working php process to get the plaintext key. Shared nothing also doesn't help you - that just multiplies the amount of places the key is placed because you're still facing the same issue: the scripts need access to the key. You could possibly devise an authentication scheme by which a script could authenticate itself to a server that would then hand out the key ... but that's susceptible to other attacks as well. So I'd probably stick the key in memory, possibly memcached. I'd encrypt it but nothing special, just making sure that you cannot get the plaintext from memcached without digging through working php files to figure out how you decrypt it. Then I'd monitor the solution to see if anything *weird* was going on, wiping memcache if something strange comes up. As should be obvious, this doesn't solve the problems. Your number one priority is blocking access to the server. Number two is making sure that noone can use the data *if* they get access but without working scripts. If someone roots the server with everything up and running, there's really very little you can do. This is getting offtopic, though, if memory serves. I believe PCI has some strict requirements on how security should be implemented. You'll have to follow those and not other schemes that may be more or less secure. Regards Peter -- hype WWW: http://plphp.dk / http://plind.dk LinkedIn: http://www.linkedin.com/in/plind BeWelcome/Couchsurfing: Fake51 Twitter: http://twitter.com/kafe15 /hype -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php Here are a couple of things which may help http://www.owasp.org/index.php/Cryptographic_Storage_Cheat_Sheet#Rule_-_Under_PCI_DSS_requirement_3.2C_you_must_protect_cardholder_data http://www.issociate.de/board/post/247319/Encryption_Key_Storage.html The biggest issue with it on web servers is simply time. If the key is too hard to get to, or unavailable due to a machine failure, then you are going to have pissed off customers/clients who won't be able to do much. The best solution is to store the CC data on a DB that is not web facing. That removes the need for the web app to hold the encryption key. You can store a hashed value, with the last 4 digits of the card and expiry on the web facing DB for any transaction processing verification. But those transactions should then move into a queue inside the secured network that is not web facing. This secured network can then take the data from the queue, find the appropriate record in the secured DB, unencrypt it and process it as normal transaction. Get back the verification of successful transaction and then queue that back into the web facing system for messaging the user. -- Bastien Cat, the other other white meat -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] How to store encrypted data and how to store the key?
I talked with a friend who actually had this implemented before and banks had signed off on it after reviewing it. load balancer (irrelevant to the security piece) web server(s) - only accepts traffic to port 80/443. can only forward requests on to the app server, one direction. app server(s) - processes the PHP/etc. has access to the encryption/decryption keys. can only send established packets back to the webserver, and traffic to the db. cannot connect outbound to the net. db server(s) - stores the data. choose how you want to encrypt. they did not encrypt data at rest in their setup, the bank would have 'preferred' it but was not willing to buy the license for the encryption plugin. however, the app tier could handle the encryption/decryption. all machines were only accessable via VPN, not the WAN. due to that, assuming physical access is not an issue: if the webserver got exploited, it could only talk to the app server using http. it has no access to the encryption key, nor the database. only one direction of communication. if the app server somehow got exploited (someone somehow got a trojan installed) it can't communicate outbound, so unless they figured some creative way to make the app server expose information through the open port only for the webserver, it's useless. and to install the trojan, typically people fetch remote files - well, the app tier can't communicate outbound. it's pretty damn secure for a web app. you could theoretically pair the app server and db server on the same box - you could probably make that work too. depends on how large you need to scale and the architecture required. anyway... anyone have any comments or holes to poke in this theory? On Wed, Jun 23, 2010 at 12:55 AM, Tommy Pham tommy...@gmail.com wrote: -Original Message- From: Peter Lind [mailto:peter.e.l...@gmail.com] Sent: Wednesday, June 23, 2010 12:22 AM To: Michael Shadle Cc: PHP-General Subject: Re: [PHP] How to store encrypted data and how to store the key? On 23 June 2010 09:11, Michael Shadle mike...@gmail.com wrote: This is somewhat related to the whole PCI/credit card discussion a couple weeks back. The consensus was basically leave it to other people - however, what if YOU are the other person? I wonder if anyone has some BKMs to share about encrypting data in a web application. A lot of people take the most obvious approach, but it's fundamentally flawed, that is: I take data from the user, I encrypt it (using PHP crypto, or MySQL crypto, etc.) and a key stored in my config file, and put it into the database. Then when I want to get it back, I just use decrypt + the key in my config file. The issue there? If you server is compromised and the database is accessable, they'll have the key to decrypt the data right off the server. They can pull down copies of everything or even write their own script ON the server itself to extract the data. This has been one thing that I have not really been able to figure out yet. You could separate the servers, and figure out some very hard way for them to communicate, but when it comes down to it, the webserver needs to access the data. For example, the webserver could be behind a fully firewalled setup that only allows MySQL traffic. However, the webserver has to access the data still. I assume the only solution is somehow storing the key in a third place, so the accessor has to get the key somehow before accessing the encrypted data. But again - how to automatically allow access for only the webapp? I thought of per-user keys, but that isn't an appropriate solution for something that needs to be encrypted using the same key. Has anyone had to implement anything like this? Is there a good whitepaper on something like this? Especially relating to HIPAA requirements. PCI would be nice too, but I'm sure once this major unknown in my mind is addressed, the general concepts are common, probably just differences in levels of firewalling, cryptography strength, physical access to the machines, etc. Please keep this on topic - this is about the people who DO have to address this issue, not something about just offload it to other guys - that's an obvious choice already, and not one that is allowed depending on the job. I haven't had to implement a scheme like this but for an app I'm working on we've been considering the same issues in order to keep member data safe. I would say your best bet is to keep the decryption key in memory while the This is something I'm very interested in hearing more about since our other discussion about PHP threads and how some list members prefer the 'share nothing' approach. That said, how would you access the memory for every individual sessions that need that decrypting code/key when nothing is shared? (I'm assuming that this would be purely in PHP :) Regards, Tommy app is running. Initialize it by hand
Re: [PHP] How to store encrypted data and how to store the key?
On 23 June 2010 20:55, Michael Shadle mike...@gmail.com wrote: I talked with a friend who actually had this implemented before and banks had signed off on it after reviewing it. load balancer (irrelevant to the security piece) web server(s) - only accepts traffic to port 80/443. can only forward requests on to the app server, one direction. app server(s) - processes the PHP/etc. has access to the encryption/decryption keys. can only send established packets back to the webserver, and traffic to the db. cannot connect outbound to the net. db server(s) - stores the data. choose how you want to encrypt. they did not encrypt data at rest in their setup, the bank would have 'preferred' it but was not willing to buy the license for the encryption plugin. however, the app tier could handle the encryption/decryption. all machines were only accessable via VPN, not the WAN. due to that, assuming physical access is not an issue: if the webserver got exploited, it could only talk to the app server using http. it has no access to the encryption key, nor the database. only one direction of communication. if the app server somehow got exploited (someone somehow got a trojan installed) it can't communicate outbound, so unless they figured some creative way to make the app server expose information through the open port only for the webserver, it's useless. and to install the trojan, typically people fetch remote files - well, the app tier can't communicate outbound. it's pretty damn secure for a web app. you could theoretically pair the app server and db server on the same box - you could probably make that work too. depends on how large you need to scale and the architecture required. anyway... anyone have any comments or holes to poke in this theory? I'm just wondering if this is a correct understanding: 1. plaintext data arrives on the web frontend. 2. It's sent to the app server 3. It's encrypted and sent to the DB server Where does the data go after step 3? Does encrypted data go back out to the app server? In which case, what's to stop me from exploiting the web-server and then sending *bad data/commands* to the app server? But maybe I'm taking this too far: are you only looking at security in terms of storage? I.e. is this merely a question of avoiding dumps of the data? Regards Peter -- hype WWW: http://plphp.dk / http://plind.dk LinkedIn: http://www.linkedin.com/in/plind BeWelcome/Couchsurfing: Fake51 Twitter: http://twitter.com/kafe15 /hype -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] How to store encrypted data and how to store the key?
On Wed, Jun 23, 2010 at 12:43 PM, Peter Lind peter.e.l...@gmail.com wrote: I'm just wondering if this is a correct understanding: 1. plaintext data arrives on the web frontend. or over SSL 2. It's sent to the app server SSL or non-SSL - your choice 3. It's encrypted and sent to the DB server encrypted or not encrypted - your choice Where does the data go after step 3? Does encrypted data go back out to the app server? In which case, what's to stop me from exploiting the web-server and then sending *bad data/commands* to the app server? But maybe I'm taking this too far: are you only looking at security in terms of storage? I.e. is this merely a question of avoiding dumps of the data? It is mainly about how to stop an exploited machine (even shell access) from accessing the data by simply looking at a PHP config file. This solves that by reducing the risk with the only WAN-accessable touchpoint (web servers, or well, technically the load balancer even) which is only accessable via HTTP or HTTPS. Feeding bad commands is always a risk, no matter what - but you could figure out how to setup an IDS system or something to only accept POST/GET without exploitable characters or anything. Suhosin type things come to mind. But again - the only way to get data would be if you craft something and use SQL injection or something to get the data out. You couldn't exploit code to download a trojan or something because the application server cannot talk to the Internet. I think it is a compartmentalized setup that would solve my original question... -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php