Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fully encrypt data in Ruby using Private Key encryption?

First, some info on our system, which is basically an eTendering solution for the construction industry.

So:

  • List item
  • Our system has multiple companies
  • Each company has multiple users
  • Each company can create multiple auctions
  • Other companies can then submit their bids for the available auctions. A bid consists of hundreds or thousands of individual items, and we would just need to encrypt the 'price' section of these records.

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:

  1. 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.
  2. When a company submits a bid for an auction, we encrypt the prices using the public key of the auction's owner company and we save them into the database.
  3. When the auction bidding period is over and the issuing company wants to generate the report the first time, we ask him to input his password and use that along with his company's private key to decrypt the prices.
  4. To make subsequent traffic faster, we cache the decrypted data (and maybe encrypt it using a simple symetrical encryption system)

So here are the questions (and we're unfortunately not security experts, so sorry if those are stupid questions):

  • Does this make any sense or is it a totally ludicrous or overkill solution?
  • Would we generate the keys using OpenSSL, OpenPGP or another solution?
  • What happens if a user wants to change his password or generate a new key? Would there be no other way but to decrypt/re-encode everything with the new key?
  • What would some of the pitfalls be with this solution?
  • Are there any better solutions that you could recommend?
like image 940
khelal Avatar asked Dec 06 '12 18:12

khelal


3 Answers

So here's my suggestion, if you want to solve this using encryption...

  • Each user and each company should generate OpenPGP (or GnuPG) asymmetric public/private key pairs
  • Each of those public keys should be uploaded to a public key server
  • Companies could optionally "sign" the public keys of the individual users, to designate a trust relationship with those users (and revoke that signature if that relationship changes)
  • The auctioneer or non-partisan arbiter would also generate a key pair and push that public key to the public key server
  • As part of an auction registration process, each user would import the public key of the auctioneer, and the auctioneer would import the public key of each user
  • A trusted third party, perhaps a SaaS vendor outside of the auctioneer, would host a service through which users and the auctioneer would communicate
  • Bidding users would create a bid by
    • signing their bid with their private key
    • encrypting their proposed price to two keys: their own public key and the auctioneer's public key
    • submitting their bid to the trusted third party service, which would need to enforce an embargo on any user retrieving bids before the auction expiration
  • At auction end, and only after auction end, the auctioneer retrieves all of the bids, decrypts them, and verifies signatures

A couple of key points:

  • It's essential that no user or company private keys are ever shared or stored within the service -- that's the only real "flaw" I see in your proposed methodology in your question. If that's the case, it would be very possible for one user to accuse an administrator of "fraud" or "tampering" with bids, as an administrator of your server would ultimately have access to the private keys of all users, since you've generated them yourself.
  • Along those same lines, it's essential that any an all communication and "bids" are cryptographically "signed" with the truly private keys by each user. This is how you would know that a bid came from one particular user and only that user, and that the bid could not have been tampered with.
  • Encrypting the bids to the public keys of the bidding user and the auctioneer ensures that the third party SaaS vendor has no introspection into the bids themselves during the blackout period while the auction is open. I believe this is the most important point to solving your problem as described.
  • Note that it might actually be preferred to encrypt each bid to a ring of all of the bidding users, if by design you want to make all bids public after the auction is closed. That would be a slight modification to my algorithm as described above.

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 ;-)

like image 167
Dustin Kirkland Avatar answered Oct 16 '22 06:10

Dustin Kirkland


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.

General Points

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.

Re: Does this make any sense?

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.

    • SSL helps mitigate this, but an errant log line somewhere along the line could very well expose the client's password by accident.

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)

Re: Would we generate the keys using OpenSSL, OpenPGP, or another solution?

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)

Re: What happens if a user wants to change his password or generate a new key?

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.

like image 40
Nevir Avatar answered Oct 16 '22 06:10

Nevir


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

like image 23
Dimitrios Stergiou Avatar answered Oct 16 '22 04:10

Dimitrios Stergiou