First, some info on our system, which is basically an eTendering solution for the construction industry.
So:
The problem that we're facing is that our large customers do not want us to ever have access to the bid prices, at least while the bidding is in progress, which is totally understandable. Right now, we are simply encrypting the prices via a symmetric encryption, so even though the prices are effectively encrypted in the database, their concern is that we have the key to decrypt the prices.
We're thus looking at some form of public key encryption system. Here is our initial thoughts on the solution:
So here are the questions (and we're unfortunately not security experts, so sorry if those are stupid questions):
So here's my suggestion, if you want to solve this using encryption...
A couple of key points:
In the interest of full disclosure and perhaps some subtle marketing, I happen to be the architect and CTO of a company called Gazzang who has implemented a product called zTrustee which operates exactly as described above ;-)
To be clear: I have a hunch that your clients are probably not willing to sacrifice all of the conveniences that come with having your system manage some of the cryptography; you should probably present several options and their weaknesses vs convenience.
Before anything else, you start start with an explicit threat model, covering every possible attack you can think of. Even if you choose not to address some of the attacks (it's unrealistic to handle everything), you'll ferret out the more obvious attacks, and have at least a basic set of steps for handling others should they occur.
I think the general premise, while overkill on the part of your customers, makes sense from a security perspective. Your clients want a cryptographically secure system; fair enough.
However, some points on your proposed solution:
By allowing the client to pass their password over the wire, an attacker (which your client seems to think could be you) needs to only man in the middle that password to gain access to the pricing data.
The only truly cryptographically secure way (as I see it) for the client to ensure that you don't have access to the pricing data is for them to encrypt it, and your system just acts as a broker for the encrypted data. This, in effect, makes you a broker of encrypted packets and public keys, but your system should never see private keys.
The question is: are clients willing to manage their own keys, or is that too burdensome to them? You might be able to automate most of it, at least (client app/website would handle storing the private key locally, and would also be responsible for gathering public keys of the other interested parties in order to decrypt their encrypted bids)
Really doesn't matter all that much; each of those options just define the container format for the public/private keys and any metadata. Use whichever one fits your language/platform best.
The main decision point should be in which encryption algorithm and key strength: RSA-2048? RSA-4096? elliptic curve? something else?
Specific to Ruby: You're probably just going to want to use the OpenSSL library, since it's part of the standard library. But to reiterate my point above: It's even better if your servers never even see the private keys (if the clients are ok with the trade off of better security over convenience)
Changing a password is trivial: the private key its self is just encrypted w/ some symmetric algorithm. Changing the password involves decrypting the existing key, and re-encrypting it with the new key. If the client were to lose their password, there is no recovery.
Generating a new key is probably safer, but requires more diligence on your part (encrypted payloads will need to identify which key they match, and clients could have multiple keys active at a time). This is a good thing, though; it is a common practice to rotate keys regularly, even if they are not compromised.
When a company signs up, we create a public/private keypair using OpenSSL for it and we save it in S3 or straight into the database. For this to be really useful, we would enforce the user to use a strong password for the private key, which would of course not be saved in the database.
I am a bit sceptical about this step. If you (the developer company) generate both the public and the private key used for the encryption it means you are 50% into being able to break the encryption. The only thing that protects your customer is the password, which you might be able to bruteforce (i am not suggesting that you will but you have the ability to do so)
If you will use PKI (or what you have described) you need to ensure that the key creation does not happen on your system. The client should create the pair on their systems and then provide you with their publoic key which you will use to encrypt the prices. The client then will be able to decrypt using the private key on which they have sole control
What would some of the pitfalls be with this solution?
The pitfall is that you are making a complex solution. Especially if you follow my advice above, then you place your trust on the customer to not "lose" the private key (and/or password) or else they won't be able to decrypt the prices. In addition, if the key leaks from their side, it's difficult to prove that your application is "innocent"
Would we generate the keys using OpenSSL, OpenPGP or another solution?
In order to prevent the pitfall of a customer losing a key, you might want to look into PGP (the commercial version does this for sure) and into the concept of ADK (additional decryption key) and "split keys". The idea is that besides encrypting with the public key of the customer you also encrypt with a "corporate" key which can only be used if y out of x number of people come together (as an example, 10 people can possess parts of the key and if 6 of them come together they can reconstruct the key). The parts can be shared amongst your company, the client, their lawyer, etc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With