Author

Topic: Secure Transaction Handling for an Exchange (Read 806 times)

sr. member
Activity: 431
Merit: 251
September 07, 2012, 01:49:56 PM
#3
Sounds like you are re-inventing Open Transactions. Probably worth your while looking at it anyway as its a lot of already written code that does a lot of the kinds of things you are suggesting...

-MarkM-


Yes, the concept is very similar.  I've taken a quick look at OT, but not enough to really understand it yet.  I'll make sure to look at it more closely to see if it would work for what I'm trying to do here before I code anything.  But I want to make sure I have a sound idea of the requirements first though.
legendary
Activity: 2940
Merit: 1090
September 07, 2012, 01:38:50 PM
#2
Sounds like you are re-inventing Open Transactions. Probably worth your while looking at it anyway as its a lot of already written code that does a lot of the kinds of things you are suggesting...

-MarkM-
sr. member
Activity: 431
Merit: 251
September 07, 2012, 12:34:16 PM
#1
I've been thinking about how an exchange could handle bitcoins securely as part of a side project I'm working on. 

Using an encrypted wallet on a firewalled non-public-facing machine seems like an obvious first step.  I'm also thinking about how to secure the application itself such that even if the app server and database were rooted, an attacker with full knowledge of the system still could not exploit it in a way that would cause coins to be lost.

So, here are my initial thoughts on how this might work.  I'm sure I'm missing something here, so I'd love it if any security experts could comment on any holes that might exist in this system:

1.  The server will have a 256-bit AES key derived from a password and a salt.  This will not be stored anywhere in the system.
   a. Password will need to be provided at application startup to "bootstrap" the app and generate the key.

2.  The server will have a 2048-bit RSA key that it will use to sign transactions in the system.
   a. The public key will be stored as plain text in a config file.
   b. The private key will be stored encrypted in a config file using the server AES key.

3.  Each user will have a 256-bit AES key derived from their password and a salt.  This will not be stored anywhere in the system.
   a. Note that this will change every time they change or reset their password.

4.  Each user will have a 2048-bit RSA key associated with their account and stored in the database.
   a. The public key will be stored in the database as plain text.
   b. The private key will be stored in the database encrypted using the user's AES key.
   c. When a user's password is changed or reset, a new RSA key will be created for the user.
      i. The old RSA key will remain valid for transactions created before the date the new key was created.  This is to ensure that in-process
         transactions (orders, withdrawals, etc.) that were signed with the old key can still be processed.
   d. The association of a key to a user will be digitally signed by the server (hash of userid + encrypted private key + public key + timestamp).
      i.  This is to prevent a user with database access from tampering with a key or associating their own key to another user
          in order to fake a signed transaction from that user.

5.  A user will be able to submit a signed bitcoin withdrawal request.
   a.  The request will be signed with the user's private key hash of (id + userid + amount + to address + timestamp)
      i.  By itself, this is vulnerable to replay attacks.  See 6(b) for solution to mitigate this risk.

6.  Requests will actually be processed by another app + bitcoind running on a separate firewalled machine with all incoming ports blocked and access only via console.
   a.  Before processing a request, the app will validate the request signature.
      i.   Calculated hash of (id + userid + amount + to address + timestamp) in request matches signed hash.
      ii.  Key used to sign the request actually belongs to the user associated with the request.
      iii. Key used to sign the request was valid as of the timestamp on the request.

   b.  The processing app will keep a separate local database with the ids of all processed transactions. 
      i.   Before processing a transaction, it will first verify that the transaction was not already processed. 
      ii.  If it was, the transaction will be rejected.  This is to protect against replay attacks.

So that covers withdrawals.  Other transactions (orders, trades, deposits, any other transactions that manipulate account balances) would be handled in a similar fashion with transactions either signed by the user submitting them or signed by the server itself.  The idea is that the server should always be able to provably audit transactions and account balances to ensure they have not been manipulated (even if a hacker had compromised the database itself)

Jump to: