9

From this earlier question, I have a general need to obfuscate a set of third-party credentials stored in a user account, which are then used in an internal Winforms software client. The scheme from the accepted answer is below:

Password Creation and Encryption:

  • User, having already authenticated with the internal system, chooses a new password P for that system, and/or changes sensitive data D.
  • Client software hashes P with SHA-512 producing C.
  • Client splits C in half resulting in C1 and C2.
  • Client uses C1 and a randomly-generated IV as the key to encrypt D with AES-256, producing S (which includes the IV).
  • Client transmits U, C2 and S to server.
  • Server BCrypts C2 to produce H (which includes a random salt).
  • Server stores U, H and S in the server.

Normal Login:

  • User enters login credentials (Username U and password P).
  • P is hashed with SHA-512 to produce C/C1/C2.
  • U and C2 are transmitted to the server.
  • Server hashes C2 with BCrypt to produce H.
  • Server retrieves user record with username U and verifies H against stored value.
  • Server transmits encrypted user data S.
  • Client uses C1 to decrypt S, producing D.

This functions beautifully, except for one issue: because it's essentially a PBKDF, if you lose the password, you lose the data. At first that was acceptable, as the data could be reconstructed; however, end user complaints about having to reconstruct their user account after an admin password reset (which essentially nulls out the encrypted data) have made it less so.

I therefore need to implement something on top of the existing scheme that allows administrative data recovery and/or password reset. I have come up with the following; please comment:

Password Retrieval/Admin Reset:

  • When changing a user password, client software additionally retrieves a common 2048-bit RSA public key K1 from the server.
  • Client uses K1 (and a proper padding scheme) to encrypt C1, producing E.
  • Client transmits E along with other user data, which is stored in the DB by the server
  • When password recovery is desired, an admin authenticates with the server and requests S and E for the user, along with K1.
  • Admin also obtains the private key K2 from offline, physically-secured storage.
  • Admin uses K2 to decrypt E, producing C1.
  • Admin uses C1 to decrypt S producing D.
  • Admin chooses a new password for the user, and obtains a new C/C1/C2, then produces S and E, all the same way the client would normally.
  • Admin transmits U, C2, S and E to the server, which BCrypts C2 into a new H and persists U, H, S and E.
  • Admin transfers the new password to the user offline or otherwise secure from observation, and returns their source for K2 to its secure physical storage.

Advantages:

  • Obviously, it solves the problem; lost or forgotten passwords can be reset by the admin.
  • Data is still secure; no information is transmitted across a wire or stored in the DB or program code that could be used in that form to obtain sensitive data; not knowing the password, an attacker must either crack AES-256 encryption or crack RSA-2048 with OAEP in order to obtain the third-party credentials.
  • While passwords are resettable, they are never recoverable; the admin never sees or knows the plaintext password the user had originally chosen. That password is the user's, and theirs alone (the password created by the admin can be treated as "temporary" and so required to be changed after one use).
  • If the admin, for any reason, doesn't have access to the specific private key of the pair that was used to encrypt the user's password-based symmetric key C1, they can still fall back to the "blow it away and recreate it" method of restoring the user account.

Disadvantages:

  • An additional piece of information must remain secure; the private key K2. This is not a human-consumable piece of information, and so must be stored in digital form; therefore that key storage must be physically isolated and secured, similar to (but probably not as well as) the private key for CA certificate generation.

The question is, is there anything I'm missing that would make this added piece of the scheme unsuitable or unworkable?

KeithS
  • 6,678
  • 1
  • 22
  • 38
  • What's wrong with generating a random encryption key, then encrypting that with both an asymmetric encryption algorithm such as RSA (where the private key is kept secret), and a key derived from the user's password (using e.g. bcrypt)? Store the two versions of the encrypted key separately. Then use the random key (plaintext to the key encryption) to encrypt the data. Maybe I'm missing something, but it seems like it has the same advantages and disadvantages, plus would appear to be a *much* simpler scheme. – user Dec 18 '12 at 19:28
  • What's wrong is that the existing scheme, using a password-derived symmetric key for the user data, is already in place and working. I can add the proposed password recovery method to it relatively trivially; the next software update can see that the field for the encrypted symmetric key is blank, and run through the asymmetric encryption at the user's next successful login. Changing the already-existing scheme would require allowing both systems to work in parallel, to support logging in the old way, then converting to and using the new way, until all users have logged in. – KeithS Dec 18 '12 at 19:55
  • 1
    In addition, the current scheme is a two-stage hash; one half of one hash is used as the key and never sent over the wire; the other is re-hashed server-side for password verification. If whatever value was used for password verification also encrypted the credentials, even with a re-hash on the server side for verification, if an attacker sniffed that hash as it was sent they now have the sensitive data. – KeithS Dec 18 '12 at 20:11

1 Answers1

6

The best cryptographers use cryptography only when necessary. That being said, this proposed design is needlessly complex. Your design incorporates two different hash functions, symmetric and asymmetric encryption. Further more you make no mention of what attacks you are trying prevent, which leads to a superstitious design that is difficult to independently verify.

Use SSL it is a beatitude and proven design. It is light weight, its free and best of all IT IS SECURE.

In terms of the "logging in" functionality. Kerberos has a proven design for identity management and mutual authentication. Kerberos is distributed which is ideal for the cloud. Its beautiful because its so simple. A kerberos ticket is similar to the C1 variable in your system, in that is carries the user's identity. However it is also has a "ticket validity period" or timeout, which your system lacks. Kerberos tickets are created using only a block cipher, a hash function or asymmetric cryptography is not required. This design element reduces the computational resources needed for authentication.

Password reset? Just use a Cryptographic Nonce stored in a database! If the know the secret then then they can reset the password. The Nonce can be protected with encryption, and this could prevent vulnerabilities like SQL Injection from reading this Nonce and resetting the password.

In terms of addressing the root of the question. You are intentionally weakening the system to attack by introducing a backdoor. It would be ethical to inform your customers that this system has a backdoor. That being said you can implement such a backdoor using a Key-Encryption Key (KEK). You should also probably read the AES Key-wrapping Specification. A KEK can be used to easily change the encryption key used for a dataset after a compromise. The same property can be used to change the "password" used to protect data.

Complexity is the worst enemy of security

--Bruce Schneier.

rook
  • 46,916
  • 10
  • 92
  • 181
  • I don't agree. Basically what I am trying to protect is an additional set of credentials to a third-party cloud system representing a key repository for sensitive data about us, our clients, and the systems and services we offer them. Those credentials are needed to connect to that cloud system as the same identity that is logging into our internal software. In addition, because people tend to use the same password for everything, I can hash the internal password all I want, but the password for the internal system is sitting right there in plain text. – KeithS Dec 19 '12 at 00:43
  • Therefore, I must encrypt the third-party password by some means that an attacker must not be able to discover, either by decompiling our internal software, obtaining a dump of our database, or sniffing traffic. Basically, I want to ensure that if an attacker obtained the third-party credentials, it was not the fault of my application. The basic scheme incorporating the BCrypted hash was the answer to that problem. Nothing an attacker can sniff, dump or decompile gives then enough information to recover the credentials; there would have to be a keylogger installed (not my problem). – KeithS Dec 19 '12 at 00:49
  • However, this was deemed a bit *too* secure. Users complained that if they forgot their password, they pretty much had to set up their account again from scratch. Hence, the recovery method, which I need to remain as secure as I can get it. Requiring admins to enter a secured, video-monitored room using a keycard that logs their entry, in order to obtain the private key, hopefully in a non-distributable form, is about as secure as I'll get, given that the building is built to standard commercial code and a few swings of an axe will get you anywhere you want. – KeithS Dec 19 '12 at 00:55
  • Last word on this; who's to say this is needlessly complex? SSL uses, as part of the standard handshake, at least two different RSA key sets (if not four, to provide two-way client-server authentication), an SHA hash and a negotiated symmetric key. How is my authentication scheme "needlessly complex" given all that rigamarole? – KeithS Dec 19 '12 at 01:15
  • @KeithS None of these problems are new, proven solutions already exist in the open source world. I like SSL a lot, their cipher suite system incorporates variants of all the proven primates such that when a vulnerability is found you can easily fall back on a secure set of primitives. NO SSL cipher suite is redundant, such as using bcrypt and sha256 at the same time. This is the opposite of your system, in that you are increasing the attack surface by increasing the complexity. If a flaw is found in bcrypt you have a problem, **when** a flaw is found in sha2 you also have a problem. – rook Dec 19 '12 at 16:00
  • BCrypt plays a relatively minor role here; its purpose is to make pounding on the front door (trying all logical possibilities of the password itself given the software) an expensive proposition. The hashed password is currently sent over an insecure network channel, so it's really easy to get that, but it only gets you the encrypted data for the user. You would then have to break Microsoft's AES-256 or RSA-2048+OAEP implementations to get the sensitive data. Am I worried about either of those? Not really. – KeithS Dec 19 '12 at 17:29
  • As far as SHA2's vulnerability, as stated, an attacker could only ever see half of the digest in a useful form without either being "on" the client computer or breaking one of two very highly-trusted encryption standards. If you're telling me that SHA512 can be cracked given only 256 bits of the digest, I'd tell you the other one plays Yankee Doodle when you pull it. – KeithS Dec 19 '12 at 17:31
  • 1
    @KeithS Just about everyone on security.se will go ape shit if you suggest replacing SSL with a home-brew system. I am one of these people. From experience I think that reinventing the wheel is one of the worst evils in the security industry. This discussion is not building a secure system, it is a learning experience for you and a waste of everyone Else's time. – rook Dec 19 '12 at 17:32
  • I'm *not* replacing SSL. I'm implementing a system for user account protection, not server authentication and secure handshake. SSL has *no* bearing on the security of stored data. I compared the complexity of this system to SSL in an attempt to show that it really wasn't that complex. If you have an issue with the complexity of the base system (no RSA, but it has the redundant SHA/BCrypt hashing and AES encryption you seem to be dumping on most) then I suggest you take it up with @ThomasPornin, who suggested it to me in the first place. – KeithS Dec 19 '12 at 17:37
  • @KeithS You expect feedback on your design, yet you leave out critical components. For instance make no mention of what mode of operation you are using with AES. Are you aware of the authenticated modes for block ciphers? Have you ever heard of a cryptographic oracle? Why do you think you can do better than the existing solutions that the rest of the world uses every day? Cryptography isn't some magic wand. – rook Dec 19 '12 at 17:40
  • ... And now you're switching horses; first it was too complex, now it's too vague. I'm done. The question got more upvotes than your answer to it, which should tell you something, but apparently you're too busy telling the senior developer of a company *in the security industry* that he shouldn't be messing around with security. Just to pacify you on your latest tirade, I'm using AES-256 in CBC mode with a CSPRNG-produced IV for each record. All implementations of the actual primitives are Microsoft's CryptoServiceProviders except BCrypt, which is Derek Slager's. – KeithS Dec 19 '12 at 17:55
  • @KeithS With CBC mode, you must worry about decryption oracles and padding oracles. As far as I can tell your design does not take these attacks into consideration. As a penetration tester I eat developers for a living, as a cryptographer I can tell you you are out of your depth. Redesign this system using an authenticated mode. Then post smaller, well documented components to security.se for review. – rook Dec 19 '12 at 18:05
  • let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/6792/discussion-between-keiths-and-rook) – KeithS Dec 19 '12 at 18:26