00545: Encrypted page store.
Description: Somebody like me want use pmwiki to store some personal information, and like to encrypt the page store. Surely, there is a solution at Cookbook/DesCrypt. But that solution use javascript and only encrypt part of the page, I'd like to suggest a solution for pure html post.
Before store the page, we need a password to encrypt the information. A choice is to use the read/write password of this page. Or allow setting a encrypt password of the page. When we view the page, pmwiki ask and check the encrypt password (if the encrypt password in session is the same as this page, then allow for viewing directly), and use this password to decrypt information.
When we modify the encrypt password, the information of this page will be decrypt and encrypt again using the new password.
And for the encrypt function, I know a rc4 pure php solution. There may be better choice.
Key management in any sort of encrypted page store is going to be a real pain. For example, the above says "when we modify the encrypt password, the information of the page will be decrypted and encrypted again using the new password". Where should that take place? Does each page have its own encryption password, or is one encryption password to be shared among a large number of pages? When is the author prompted for the new encryption password?
And, of course, if the password used to encrypt the pages is ever forgotten or lost, then the page contents are irrecoverably lost.
At any rate, I'm likely to leave this for a cookbook recipe. :-)
--Pm
I'm also interested in such a function but I do agree, it is better to do this via a cookbook recipe. Maybe Cookbook/CompressedPageStore could give a starting point for the save handling.
My ideas what would have to be done:
- Provide in attributes page another entry (encrypt) where the encryption password could be set. When a password is set the page is encrypted on save. When no password is set the page is saved without encryption.
- Some parameter has to be defined, how to separate between encrypted and not encrypted page.
We just have to find a good script that can be used for encryption. The mcrypt liblrary is ideal for that but you have no chance, when you don't have access to the PHP installation.
We could use that one:
http://pear.php.net/package/Crypt_Blowfish/docs/latest/Crypt_Blowfish/Crypt_Blowfish.html
The questions are:
- Encrypt only text or whole file?
- How should PmWiki know that the file is encrypted?
- Is there a way to create a new save function thst does the encryption and then hands over to the original save function? (I never used OOP)
-- Klonk
In the above it says:
- Provide in attributes page another entry (encrypt) where the encryption password could be set. When a password is set the page is encrypted on save. When no password is set the page is saved without encryption.
Question:
- If the encryption password is in page attributes, how/where would the encryption password itself be stored -- would it be encrypted or in cleartext in the page file? (If encrypted, where do we get the key to decrypt it; if cleartext, what's to prevent someone from using the cleartext password to decrypt the file directly?)
--Pm
Surely, I agree it should be a cookbook solution.
My initial idea is like this: we could store the password's md5 code as cleartext in the page file. When we edit or view a encrypted page, pmwiki ask for the password and check if it is right. Thus the real password will not be saved.
A simple method is make each page keep its own encrypt key and provide no global default key. If we change the password of a page, we will have input the old one, then pmwiki know both the old key and the new one, could do the re-encrypt.
Another solution is give a site wide global default encrypt key, and we should give out a function to list all the pages encrypted by the default key. If we change the default key, and all the pages using default key will be re-encrypted.
Because we haven't save the real keys, if we forget a key, then we have no way to get the real text. This may be a solution with enough security. If a person get the file in wiki.d directory, it's hard to decrypt it. But if we don't use HTTPS when we submit encrypt keys, the keys may be sniffed.
My initial idea is encrypt the whole text, but it may have other choice.
We need a pure php encrypt/decrypt function to complete the encrypt progress. A choice is the rc4 lib at [(approve links) edit diff] .
Why store the password at all?
Just some kind of marker that the file is encryted would be totally sufficient. This is of course quite dangerous: When a false password is entered the user will only see some strange characters, nothing else.
When entering the password keep it in a cookie. Of course then the "logout" action has to be used to get rid of it or better the lifetime of the cookie should be limited.
I think pages should be encrypted seperately but there should be a way to provide a global encrypted password in the config.php file. This should be handled the same way as the other passwords (stored as hash).
-- Klonk
Why can't PmWiki include something like the "Mcrypt"? [(approve links) edit diff]
I wrote a client-sever Java-based backup software years ago, which never stored the encryption key anywhere -- it was provided by the user on the client side. To be more specific, I had 3 parameters on the login screen for: user, password, encryption key (first two for authentication; last one for encryption). I can see something similar in Pmwiki, where the key could be passed in the URL somehow. While I could encrypt the data on the client since it was "thick" Java client, in the case of PmWiki, the data would be sent over the wire as plain text but stored on the server in an encrypted form to avoid prying eyes from deciphering the text. That way, there is no need for Javascript. Granted the data can be hijacked but perhaps using HTTPS can get around that.?
-- Ben
Again, the problem isn't the encryption algorithm (mcrypt is fine), but rather the management of any decryption key(s).
If we say the user must supply the decryption key on the client side, then all users who are going to access a page would have to know and supply its encryption key. Perhaps this would work for small groups, but it's obviously not workable on a large public wiki.
In the case of a single person using encryption on a wiki -- if the key is ever lost, then the page contents are irretrievable.
Implementing encryption of the page files itself is quite simple. Keeping track of the keys is the difficult part (from a management perspective, not a programming one).
Pm
A Key Management Scheme
I think that key management could be done by separating the keys used to encrypt each page and the passwords used to access the keys. Each page would get a randomly generated key, a "page-key", and be encrypted with that key. The page-key would then be stored in the page-key management infrastructure which could have various implementations. This page-key would not ever need to be changed, even when passwords change.
One form of page-key management could be implemented with a directory called "page-keys". In this directory there would be various key files which would be bound to a specific password for a user or group (role) depending on the authentication method being used. So, for each combination of password that can be used to log into the site, a separate key file would exist. This key file would contain all the page-keys to all the pages that this particular password can access.
The page-keys in a key file would be encrypted with a public key for this file. This public key would be stored unencrypted at the beginning of the key file allowing anyone to add page-keys to this file without necessarily being able to decrypt the file contents. The use of PKI here is important to ensure that any user creating a page does not have to know the passwords of all the other users/groups allowed to access this page.
Finally, the private key for a key file could be encrypted in the key file with a password allowing the private key to be something obtuse generated along with the public key, but the password can be something simpler for users to remember/type. This makes it very easy to change a password, simply re-encrypt the private key for one key file and voila, done. No need to re-encrypt any other pages, files or keys!
A scheme like this would even allow for a (or several) site wide admin passwords which could be used for recovery.
A Speed Optimization
One potential valuable optimization to this scheme that can be used if needed to improve browsing speed would be to use a dual encryption mechanism for page-keys within a key file. As page-keys are added (by others) to a key file they could be encrypted with the key file public key. But since decrypting with a private key might be too expensive for normal use, once decrypted by a user with the password for a key file, this page-key could be re-encrypted with their password instead. Since password based encryption is likely to be symmetric, it is likely to be very fast and better suited for normal browsing. The tradeoff, of course, is that when this password needs to be changed, all the page-keys in that particular key file will potentially need to be re-encrypted, but since we have the new password at this time, this encryption can be fast since it can also be symmetric!
A Further Security Improvement
Due to the fact that this scheme will potentially be used to protect against filesystem snooping, it might be advisable to assume a system compromise whenever a password is changed. If that is the case, we should assume that anyone having access to the changed password had access to the private key in its key file and to all the page-keys in the same key file; these should all be changed at this time. Changing the local public and private key need only be done for the current key file. But, changing all of the page-keys for all of the pages in that key file could be very expensive! This would require selecting new page-keys for these pages, re-encrypting them with the new keys and redistributing these new keys to all the key files which need access to these pages. Page-key redistribution requires re-encrypting each page-key with the public key for each key file that it is in.
FYI WikiSh provides an alternate approach to encryption via mcrypt. As a development platform rather than an application recipe itself it does not attempt to solve the key management problem, but the capability is there to encrypt/decrypt any textfile or page which WikiSh has read/write access to.
--Peter Bowers April 29, 2008, at 03:47 PM
Or see EditCrypt.
--Peter Bowers August 21, 2008, at 02:13 PM
My question is, why bother with encryption?
Scenario 1: only the wiki administrator has server access
Are passwords not enough to keep the general public from reading/editing pages?
Scenario 2: a person with malicious intent has server access
In this case all bets are off because anyone with server access can simply delete files/keys and then no one, including the owner, has access to the information.
I would recommend not placing sensitive information on the internet unless it is absolutely vital to do so. Keeping in mind the resources involved in implementing this, I feel it would be best left to a recipe rather than the core. Ian MacGregor November 01, 2013