I have a client with a security policy compliance requirement to encrypt certain files on disk. The obvious way to do this is with Device-mapper and an AES crypto module However the current system that is already in place is setup to generate individual files that are encrypted.
Basically they have an apache server using SSL and basic/digest style authentication, and they need to decrypt encrypted files from AES on disk, before re-encrypting them with an SSL. (obviously I can use mod_php, mod_perl, however the idea was to keep static files only on this box)
Do I have any options for decrypting files on-the-fly in apache?
I see that mod_ssl and mod_session_crypto do encryption/decryption or something similar but not exactly what I am after as they are encryption on-the-wire and I am looking for encryption on-disk.
I could imagine that a PerlSetOutputFilter would work with a suitable Perl script configured, and I also see mod_ext_filter so I could just fork a unix command and decrypt the file, but they both feel like a hack.
I am kind of surprised that there is no mod_crypto available...or am I missing something obvious here?
Presumably resource-wise the perl filter is the way to go?
This is a facinating problem. I've been in similar situations where I was required to solve a problem the wrong way. That being said, I'm not aware of a general purpose crypto module that will let you decrypt static files as they are served. I searched for several hours but I wasn't able to find anything. That's not surprising as it seems like a fairly specialized problem.
Nonetheless, I see several options.
Action decrypt /cgi-bin/decrypt.pl
andAddHandler decrypt .html
will cause all requests for files ending in .html to call /cgi-bin/decrypt.pl which will need to read, decrypt, and serve the file. See http://httpd.apache.org/docs/current/handler.html#examples.I took the liberty of implementing a proof of concept of the fourth option which I'll share here. I chose PHP in this instance because it's ubiquitous, it usually contains the necessary crypto functions, and it's fast since it's an Apache module written in C.
Assuming that all encrypted files are stored in a directory called
data
and are encrypted using the same key, I created the directory in my document root then created an encrypted file using OpenSSL.Then I created
decrypt.php
in my document root with the following content:If your content is not base64 encoded then you can remove the first line in the decrypt function which reads
$encrypted_data = base64_decode($encrypted_data);
.Finally, in my Apache configuration I added the following entries:
Now any file requested from
http://www.example.com/data
will be decrypted and served, including from within subdirectories. Since the rewrite condition is limiting the rewrite to files, directory indexes still work. I have the PHP script determine the MIME type of the decrypted content and update the header accordingly so I can serve encrypted images, documents, web pages, and so on.This probably won't be as fast as a custom Apache module, but it should be close. If you're going to be serving a lot of encrypted content and performance is an issue, you might be able to speed things up a little bit by installing the Alternative PHP Cache so the PHP page doesn't have to be compiled for every request.
Please keep in mind that you may need to increase the settings for PHP's memory usage if you are decrypting large files.
1 You said that you feel like this option is a hack. Why? Although the result may be slow, mod_ext_filter is a supported core module and will do the job once you write a filter program for it to use.
2 I borrowed the decrypt() function from http://us3.php.net/manual/en/function.openssl-decrypt.php#107210.
If it's securing files you're after, and providing a secured trade route, you may want to look into secured webdav w/mod_ssl:
However, this will not encode files into an encrypted archive. It will only transfer the file encrypted and provide a level of authentication and authorization for file access.
Don't roll your own crypto. Just don't. You can never be sure it's secure, and the first you will hear of it being broken is when Anonymous posts your company secrets on Pastebin.
Use the tools that already exist (e.g. dm-crypt/LUKS for Linux systems, or BitLocker for Windows systems). They are well understood, and any reasonable security auditor will know what they are and that they work.
If the security auditor insists on this less-than-ideal setup, fire them for incompetence.