Skip to content

Instantly share code, notes, and snippets.

@ORBAT
Created May 26, 2014 19:46
Show Gist options
  • Save ORBAT/7b8f5c705f01073015b3 to your computer and use it in GitHub Desktop.
Save ORBAT/7b8f5c705f01073015b3 to your computer and use it in GitHub Desktop.

A standardized formulation of the UserID and session token would fix that.

We could actually just use the existing HTTP Auth protocol and provide end to end security.

This uses a challenge and response between server and client -- It's used on password protected pages and calls up that browser popup. I'll link to a protected page of my own so you can see it.

This has the benefit of coming up OUTSIDE the browser page, so that it's potentially far less spoofable when paired with a "remember account" system as in all major browsers. A spoofed page wouldn't be remembered and wouldn't auto populate. Hint: if you are typing in a login on a browser page, it's too late. You need to put in your password BEFORE the page ever comes up if security is requested.

The client and server could exchange nonce values, perform the HMAC( password, nonce1+nonce2 ) = A1; or similar to create the A1 proof of knowledge. Now, instead of using A1 in the clear to prove to the server AND client that both ends know the password we just key our waiting TLS cipher with A1, and begin using an encrypted connection immediately, no more handshake than that. Only the client and server have the pre-shared password. No PKI certificate authority need be used. We already have logins at all the places we want to secure anyway.

The proof of knowledge keys the ciphers. This isn't rocket science, folks. But we don't have this because it give us a real chance to have actual security: We could go to our bank personally and set our password. We could exchange the password out of band and no MITM could ever intercept that communication.

Client Sends: Login Name + Client Nonce
Server Sends: Server Nonce or [Forbidden]

Both HMAC( PW, N1+N2 ) = A1, and key the cipher with A1, and begin talking. They can send whatever they want at that point and if the other end can decrypt it then they are authenticated. Optimally PW would actually be HASH( PW ) instead, which could be PBKDF2 or 1000 iterations of SHA256/512/3, etc.

A very small Session: [hash] of, say, 4096 bits or so could allow the server to encrypt the hash of the user's password and this STANDARD session ID would be given to the user as a session token. The decryption key for this would be known only to the server.

That way on a new connection the server sees the User, Nonce1, and SessionID token. It decrypts the small SessionID and gets the timestamp, Server_Nonce, Client_PW. If it hasn't timed out, it can immediately reply by performing the HMAC( PW, N1+N2 ) = A1 and seeding the connection. To prevent replay attacks all subsequent N1 and N2 could instead be generated by N2 = HMAC( PW, N1 ); N1 = HMAC( PW, N2 ) such that there is a schedule and dependency. This would require each reply to include a newly encrypted SessionID token.

The token is technically a "magic" number AKA a "magic" cookie, however, this cookie is only sent while logged in. Logging out erases it completely. The removal of the (misspelled) HTTP Referer header and a policy to only ever send the SessionID to the page listed in the address bar would eliminate the use of this token as a tracking cookie.

Furthemore the user name itself could be generated via HMAC( User_salt, server_domain_name ); This way all user IDs are anonymously identified. The user agent could change the user_salt to immediately become a new identity. Each website would get a different password hash as well if the PW hash was also computed thus: HMAC( PW, domain + user_salt ) Thus the user could have one login for the entire Internet, while using a different login credential for every website.

The websites could associate the user name hash with a human readable nickname to be known as. This way the ID is always unique even if the names are the same. That's much better than relying on email addresses for uniqueness. Email verification is outside the scope of authentication.

The only time you need PKI / public key crypto is during account creation to exchange the password, or upon password reset (but not password change, you know the old one). PKI is not required for authentication thereafter. The window of exploit is so small that a simple Diffie Hellman key exchange could be used to transmit the password without PKI. Any MITM would have to maintain the breached connection. This could be trivially defeated by exchanging the password out of band, in person, or via mail or any channel the MITM is not in control of.

This brings me to my next point on security. The initial account creation DH key exchange mentioned above could be performed through a proxy - A trusted 3rd party, like your bank, that you have already established an out of band pre-shared key with.

The bank (or other existing authenticated trust) could not decrypt the connection, and the MITM would have to be actively MITM-ing the bank's connection to your endpoint as well as your connection to the endpoint outside of the bank. Passive attacks would be defeated. This would allow you to establish new accounts and create pre-shared keys with the endpoints authenticated without using the PKI system at all: It puts who to trust back in the users hands instead those of Cert Authority's.

The reason we want to avoid the PKI system is that it inserts a potential MITM in every single "secure" connection: The Cert Authority. Considering that gag-orders exist and that state governments can compel a CA to generate them a cert (or hand over the keys), the current CA system offers ZERO security. It has NEVER offered ANY security. Verisign was the only CA for a long time, and simultaneously they were selling an information interception "product" to governments. See? Don't you think that "intercepting communications" and "securing the world's communications" are a conflict of interest? The IETF, ICANN, and assorted web authorities didn't think so... Neither did browser vendors who trusted that root for you; Ah, now you're getting the picture... They're all either evil, or inept.

So, problem with my approach is that it would give you actual security, and uses only simple well understood crypo primitives like DH exchanges, hashes and HMAC -- far too little room to squeeze in big holes like Heartbleed: The SessionID makes that irrelevant, connections can be resumed without intermediary heartbeats. That the IETF isn't distancing itself completely from the CA system, or that it EVER thought the CA system offered security is enough to tell us that they should NOT be in charge of ANY protocols or governance of the Internet whatsoever. They should be fired. If they can not be fired, we should build a new Internet, the current one is compromised at every level.

I know the above system can be implemented, it's the protocol I designed for my custom VPN system which lets me log in securely and/or authenticate to other VPN system instances (at my home, business, etc).

Also: PGP trust graphs exist, but it's a somewhat convoluted protocol too.


TL;DR: We use HTTP Auth's proof of knowledge to key SSL; We allow users to turn off cookies and still be able to log in via the standardized session token / auth. Existing sites with established pre-shared key can proxy a DH key exchange with new sites to set up new accounts. We can actually ditch the corrupt PKI / CA system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment