I'd like to encrypt IP addresses in my MySQL database, with the following constraints:
- Does not need to be resistant to attackers that can execute queries.
- Must be resistant to attackers that have access to files on disk.
- Must be able to validate an IP against the encrypted form, to check if it matches.
- Checking against
10.20.30.*) would be useful too.
- Any form of key or password cannot be entered on system startup, as this will be running on a server in a datacenter, and logging in via SSH every reboot is a pain I can do without.
I'm currently using separate database connections to give better privilege restrictions, with a separate table for passwords. I'm also using MySQLi and semi-automated code reviews to ensure there are no SQL injection holes.
With a non-salted (i.e. deterministic) hash mechanism, it would be easy to compute all possible IP hashes. With a salted hash, that problem is reduced, but it's still not much better if an attacker is just trying to break one IP hash. Of course, all of this prevents wildcard searches, too.
Is there a solution to this?
After some thought, I've come up with the following scheme:
- Webapp has a 4096-bit RSA public key embedded in the source, I keep the private key in a TrueCrypt volume on my home machine.
- When inserting entries into the logs table, the IP is padded with a random string and encrypted with the public key. This makes decrypting it impossible and makes the encryption non-deterministic.
- The webapp provides an API for exporting the logs, which can only be accessed over SSL by authenticated admin users.
- I write an application to use the API to browse logs my home machine, using the private key to decrypt the IP addresses.
- When an IP address is banned, the IP is stored in plaintext in the bans table.
Any comments or suggestions?