4

I'm giving each of my users an unique Blocktrail wallet that is protected by two API keys (which the server knows) and one passphrase (unique to each wallet).

I want the wallet's passphrase to be unavailable to anyone but the logged-in user (session persistent), so that nobody, even server administrators, can look at the wallet's password and make transactions from the wallet.

I'm already encrypting user account passwords with bcrypt.

This is what I would ideally like to implement:

  • A passphrase that only a logged in user "has access" to. (Not directly, but through their session).
  • That the passphrase is available for when the user decides to make a transaction from within the client UI (the passphrase is needed in order to make transactions), but that the user isn't required to type in a second password or type in their account's password every time.
  • That nobody is able to know what the passphrase is for any specific user, not server admins looking at databases/server sessions, not hackers breaking into the server and writing scripts that leak the passphrase, not myself.

Is this possible at all? My guess is that I'd have to somehow derive a hash, perhaps, of the user password before encrypting it with bcrypt, use that as the passphrase and store that in the session, or probably in a cookie (with additional security?). But then again, administrators sneak-peaking at the server can look at whatever is stored in each session, retrieve the passphrase, and steal the bitcoins, right? And also, I think that storing a hashed password client side wouldn't be such a good idea.

I'm really new to security, so I have no clue as to what would be the best approach for this. Or perhaps I am being too paranoid, and should just use the bcrypted password or a random string (stored in a database) as the wallet's passphrase? (Considering two API keys are also required).

I'm just looking for a hint in the right direction, since I don't even know if what I want is even achievable. Thanks.

700 Software
  • 13,807
  • 3
  • 52
  • 82
Tarman
  • 41
  • 2
  • 2
    General rule of thumb: if something is stored on the server, then the server admin can get access to it later. You'll probably want to store the wallet password (or some information that lets you derive it) on the _client_. e.g., by using cookies, NOT by using session storage. – Soron Jul 29 '15 at 03:03

2 Answers2

1

I want the wallet's passphrase to be unavailable to anyone but the logged-in user (session persistent), so that nobody, even server administrators, can look at the wallet's password and make transactions from the wallet.

  • That nobody is able to know what the passphrase is for any specific user, not server admins looking at databases/server sessions, not hackers breaking into the server and writing scripts that leak the passphrase, not myself.

While you can protect this against storage, an Administrator can put in some extra logging to capture this information. There's nothing you can do about that, except store the secret on the Client as @Ethan suggested. (which could be better or worse for security depending on who your clients are)

I'm going to answer with the assumption that you decided that the server needs access to the secret directly. (in which case also storing on the client would be pointless)

You can prevent plain storage server-side, assuming no malicious logging has been installed.

I'm already encrypting user account passwords with bcrypt.

Encryption is reversible with the key. Hashes are one-way. BCrypt is a hash, not encryption. (and that's a good thing)

Make sure you have a strong work factor. It should take at least 100ms (with appropriate DoS protection) to calculate the BCrypt hash. Note that attacker's hardware (should the hash be stolen) will probably calculate these hashes much more quickly when they try to brute-force.

A passphrase that only a logged in user "has access" to. (Not directly, but through their session).

When the user logs in, the server will have the information needed to decrypt the secret.

isn't required to type in a second password or type in their account's password every time.

There is going to be some password that decrypts the secret initially. This can either be the first password they use to log in, or a 'special' password if you prefer. After that, the secret will be continuously available as a part of the login session.

Is this possible at all?

Good question. The answer is Yes, I've outlined how this can be done in the below question. Basically you just need to derive encryption keys from the user's password, and then from the session token. Both of these should be hashed (not just the password) so that the attacker cannot access the original text from which the encryption key was derived. The Session Token should have enough entropy so that you can use a Fast Hash.

Once you have the encryption key management worked out, you can just store the encrypted secret on the server.

How can we serve sensitive encrypted data without storing the key? Should I use user-defined passwords for keys?

Except, in your case, instead of serving the encrypted data, you'll just be using it internally on the server.

Please read this over, and post a new question or comment if you don't understand how it can apply to your situation.

And of course, make sure your application is secure from attackers (non-admins) to begin with. That is the most important thing.

700 Software
  • 13,807
  • 3
  • 52
  • 82
-4

I hope I'm understanding the question correctly, but why not hash the passphrase with SHA-256 and store the result in a db. There is no encryption key so you can't reverse it and if somebody gets there hands on the hash and submit it it will be hashed again and rendered invalid.

user3632719
  • 129
  • 4
  • This would protect - weakly - against attackers who have only read access to the database, but it doesn't protect against server admins (who access to the database, the code, and the wallet). A single round of SHA-256 is pretty weak these days, though; the OP has already mentioned use of bcrypt, which is much stronger. – Soron Jul 29 '15 at 03:38