0x00 Posted November 11, 2015 Share Posted November 11, 2015 So, just had a quick play with the built in mysql encryption functions, here's the initial premise: $tn=$db->prefix."priv_store"; $db->table_insert($tn, "'','Title 1',DES_ENCRYPT('my text data','password'),0"); // 1 $a=$db->raw("SELECT * FROM ".$tn.""); foreach($a as $e){ echo "".$e['title']." :: ".htmlspecialchars($e['content'],ENT_QUOTES)."<br />\n"; } echo "<br /><br />\n"; $a=$db->raw("SELECT title, DES_DECRYPT(content,'password') AS content FROM ".$tn.""); foreach($a as $e){ echo "".$e['title']." :: ".htmlspecialchars($e['content'],ENT_QUOTES)."<br />\n"; } When the data is first selected (without password), nothing is retrieved. Which at first glance is probably a good thing. However, at some point I want to offer backup features... To start with when considering key storage my first thought was, if I store users passwords in the database then I may as well not encrypt the data... So my second thought was generate the key based on the users password as they log in and store this key in their session, but that blows the backup question out of the water because nothing is returned if incorrect password passed. I also wondered at the possibility of the case where a cracker has full access to the server and can grab the session files directly (?), also in some cases I do want to offer "stay logged in" feature. Any ideas for this type of protocol? e.g. is it better to use mcrypt with PHP and store the result in the DB, even though that handles the backup situation it doesn't cover the session files. Am I wrong about not being able to get the encrypted data from the DB for backup? etc, etc... Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/ Share on other sites More sharing options...
QuickOldCar Posted November 11, 2015 Share Posted November 11, 2015 You are better off sticking to password_hash and password_verify Set users in a session as name or id. As for remember me just store a token in a cookie for that user and check if exists, if does exist then set the session name that user Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526170 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 No this is for encryption of stored user content, not hashing. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526171 Share on other sites More sharing options...
maxxd Posted November 11, 2015 Share Posted November 11, 2015 No this is for encryption of stored user content, not hashing. Right, but the thing is - especially with passwords - you want to hash the submitted value before you send it over the line to the database. So use password_hash() before you insert the value into the database, then password_verify() after you retrieve it (and before you log a user in). Also, encryption of passwords should be a one-way thing; you should never be able to decrypt a user's password. That way, if the database is compromised, the hacker isn't getting any useful password information. If the user has forgotten their password, a new temporary one should be generated for a set amount of time, during which the user can log in to the system (using the auto-generated temporary password), and reset his or her permanent password. Which again, should be hashed (or encrypted - there's a difference between the two, but it's early and I can't rightly recall exactly what that difference is) before being sent to the database. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526185 Share on other sites More sharing options...
Jacques1 Posted November 11, 2015 Share Posted November 11, 2015 The example implementation is pretty much the worst you can possibly do with regards to encryption. DES is a toy algorithm from the 70s which was deliberately weakened due to export restrictions. Last time I checked, it could be broken in less than a day. Then you use the infamous ECB encryption mode known from the Adobe hack. And finally you abuse a human-readable string as the “key”, turning the already shaky implementation into a joke. To be blunt: With this kind of encryption, you're better off storing the data as plaintext. That's at least honest. Personally, I very much doubt that encryption even makes sense for the average website, because it's a lot of trouble for a very small benefit. Without a hardware security module, proper key management is virtually impossible. You definitely cannot stuff your keys into the session files, because then you have a folder full of keys with no access control and no cache management (the session garbage collector only runs occasionally). So really the only option is to have a single application key which is used to encrypt the data before you store it in the database. But your database probably is on the same server as the application? Then your key is stitting right next to the ciphertext, which isn't very useful. Implementing encryption with a low-level library like Mcrypt is also extremely difficult: You need to choose an appropriate algorithm and a sensible cipher mode. You have to generate a perfectly random initialization vector for every single plaintext and store it in the database. Encryption doesn't prevent the data from being manipulated, which is most likely an issue as well. So now you have to worry about authenticated encryption. This task is almost impossible for a layman, so you'll end up giving your users a false sense of security instead of actual security. If at all, you'd use a high-level library. But then again: What's the concrete benefit? Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526187 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 The login system is already as you two are describing, using one way hashing algorithms as signatures for passwords. Here I'm encrypting (not hashing) actual data which will require to be decrypted, for this a password is required, the question is about how / where to store the user / site encryption password(s). (Personally I'd prefer passwords for each user.) The issue is, if say use the login password (or some derivative of it) to encrypt / decrypt then it must be stored somewhere to be used after login, but the issue is the same if use a different password (e.g. at login use user pass to decrypt their encryption password), where to store it, especially with "stay logged in" situations. I understand hashing and that its not actually encryption (as is generally banded about). Here I'm trying to protect user data even if the system is breached at the shell level with escalated root privileges (i.e. they can grab sessions files from /tmp or otherwise). e.g. how to store (non login) passwords on a compromised system? Or even a protocol which keeps them secure from general DB or script hacks (e.g. with file IO as server user / group) Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526188 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 The example implementation is pretty much the worst you can possibly do with regards to encryption. DES is a toy algorithm from the 70s which was deliberately weakened due to export restrictions. Last time I checked, it could be broken in less than a day. Then you use the infamous ECB encryption mode known from the Adobe hack. And finally you abuse a human-readable string as the “key”, turning the already shaky implementation into a joke. To be blunt: With this kind of encryption, you're better off storing the data as plaintext. That's at least honest. Personally, I very much doubt that encryption even makes sense for the average website, because it's a lot of trouble for a very small benefit. Without a hardware security module, proper key management is virtually impossible. You definitely cannot stuff your keys into the session files, because then you have a folder full of keys with no access control and no cache management (the session garbage collector only runs occasionally). So really the only option is to have a single application key which is used to encrypt the data before you store it in the database. But your database probably is on the same server as the application? Then your key is stitting right next to the ciphertext, which isn't very useful. Implementing encryption with a low-level library like Mcrypt is also extremely difficult: You need to choose an appropriate algorithm and a sensible cipher mode. You have to generate a perfectly random initialization vector for every single plaintext and store it in the database. Encryption doesn't prevent the data from being manipulated, which is most likely an issue as well. So now you have to worry about authenticated encryption. This task is almost impossible for a layman, so you'll end up giving your users a false sense of security instead of actual security. If at all, you'd use a high-level library. But then again: What's the concrete benefit? I know its limitations and would prefer to use blowfish and have my choice of block mode (been a while I checked to see what algorithms mycrypt has, but it does give control over block mode). As for perfectly random IV, well, I'll guarantee it to be unique for the key. Data manipulation can be prevented using the right block mode! As you say, storing in session files isn't secure, hence the initial question. Also the single application key is vulnerable to all the aforementioned if has root privileges (if considering key is initialised at mysql startup, e.g. when chrooted) Even if using a standard package, say PGP, the key is required or required to be stored and encrypted by another... Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526190 Share on other sites More sharing options...
scootstah Posted November 11, 2015 Share Posted November 11, 2015 (edited) Here I'm encrypting (not hashing) actual data which will require to be decrypted, for this a password is required, the question is about how / where to store the user / site encryption password(s). (Personally I'd prefer passwords for each user.) You could just store it in the database. But, you'll need to add the user's key to a static, secret site key in some way. If you simply use the user's key from the database to encrypt/decrypt, then the encryption is effectively useless because if there was a database breach, the attackers could just decrypt the data with the stored user key. If you add the user's key to a static site key, they would also have to compromise that key in order to decrypt. Edited November 11, 2015 by scootstah Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526191 Share on other sites More sharing options...
Jacques1 Posted November 11, 2015 Share Posted November 11, 2015 What you want simply doesn't exist. Unless you're willing to spend thousands of dollars on dedicated crypto hardware, the best you'll get is some half-assed toy encryption. And you may not even get that. I know its limitations and would prefer to use blowfish and have my choice of block mode (been a while I checked to see what algorithms mycrypt has, but it does give control over block mode). Blowfish is obsolete as well, and Mcrypt is an incredibly poor library. If those are your choices, forget about it. Data manipulation can be prevented using the right block mode! What are you talking about? Even if using a standard package, say PGP, the key is required or required to be stored and encrypted by another... PGP/GPG never claimed to work on a compromised system. It doesn't. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526192 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 What you want simply doesn't exist. Unless you're willing to spend thousands of dollars on dedicated crypto hardware, the best you'll get is some half-assed toy encryption. And you may not even get that. Even simple encoding would defeat many script kiddies... Blowfish is obsolete as well, and Mcrypt is an incredibly poor library. If those are your choices, forget about it. What would you suggest then? What are you talking about? Some block modes use the previous block as an input, so if they are changed then what's after becomes useless, I'll read up as to which later, but see CBC here: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation PGP/GPG never claimed to work on a compromised system. It doesn't.No, I wasn't saying it did, quite the opposite in fact. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526198 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 You could just store it in the database. But, you'll need to add the user's key to a static, secret site key in some way. If you simply use the user's key from the database to encrypt/decrypt, then the encryption is effectively useless because if there was a database breach, the attackers could just decrypt the data with the stored user key. If you add the user's key to a static site key, they would also have to compromise that key in order to decrypt. And that's the point, on a fully compromised system, all the files are accessible too, even the root file used when starting up the database. * You refer to the key, so you can have numerous keys for different purposes (https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_des-encrypt ). I did wonder about the concept of rewriting the keyfile but that would require sudo privileges on the file that we're trying to protect, cyclic madness However, storing a key in a file does protect in the case of only the db being compromised, not if they can write to php files or execute arbitrary code (or shell). As you said, manipulating a site key with db user keys would provide a level of protection in the scenario of database compromise only. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526199 Share on other sites More sharing options...
Jacques1 Posted November 11, 2015 Share Posted November 11, 2015 Even simple encoding would defeat many script kiddies... Script kiddies (as well as professional attackers) are defeated through secure programming and competent system administration, not toy cryptography. Instead of wasting many days or even weeks on a highly questionable feature, it makes much more sense to spend a few hours on hardening the server. Do you have prepared statements everywhere? Content Security Policy? Clickjacking protection? Anti-CSRF tokens in all forms? Minimal database privileges? A separate PHP-FPM pool and Unix user for each website? What would you suggest then? Secure programming competent system administration. Some block modes use the previous block as an input, so if they are changed then what's after becomes useless, I'll read up as to which later, but see CBC here: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation CBC has nothing whatsoever to do with authenticity. It's actually trivial to make the first block produce arbitrary plaintext by changing the initialization vector, and the other blocks aren't protected either. Authenticated encryption requires a correctly implemented combination of a cipher and a message authentication code (like Encrypt-then-MAC). There are also some special modes like AES-GCM which inherently provide authenticity, but those never made it into PHP, and I'm not aware of any plans to add them. But why are we even discussing this? It's not the job of a web developer to implement cryptographic algorithms. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526201 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 A) PHP-FPM TBH I dunno! The rest yes We've discussed them B) But that's a different thread somewhere... C) No that's for hashes n such but it is for data tampering... N) Why not, I use a web portal for many webApp related api features, great for scoreboards n settings n such. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526202 Share on other sites More sharing options...
scootstah Posted November 11, 2015 Share Posted November 11, 2015 However, storing a key in a file does protect in the case of only the db being compromised, not if they can write to php files or execute arbitrary code (or shell). Of course not. If your physical box or codebase is compromised then all bets are off. If your app can encrypt/decrypt, then attackers can encrypt/decrypt too (if they have access to your box). There's not really any way to get around that, except to not let attackers compromise your box. You have to take a step back and assess your realistic threat model here. What exactly are you protecting your data from? If you just want to protect data in your database and over-the-wire, then basic encryption as I've described should be sufficient. If you want to protect your server from NSA scrutiny, then no, you're in way over your head. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526238 Share on other sites More sharing options...
Jacques1 Posted November 11, 2015 Share Posted November 11, 2015 C) No that's for hashes n such but it is for data tampering... What? I don't understand what you're saying. N) Why not, I use a web portal for many webApp related api features, great for scoreboards n settings n such. That doesn't make you a cryptographer. If you absolutely must have encryption, no matter how stupid it is, at least use a high-level library like libsodium which takes care of all the ugly details instead of relying on the developer to do that. Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526239 Share on other sites More sharing options...
0x00 Posted November 11, 2015 Author Share Posted November 11, 2015 Stupid... lol you're a funny one! Quote Link to comment https://forums.phpfreaks.com/topic/299433-encryption/#findComment-1526246 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.