Example:
- long-term key expires Dec 2006
- short term expires end of week, get new one each week
Standard trick:
- Certification auth. vouches for long term key: "The public key x (long term key belongs to Ed W Felten, signed RSA"
- Ed's long-term key vouches for short-term key: "The public key y belongs to EWF, signed by x"
Secret splitting of private keys
RSA private key = (d,N) and
RSA(d,N) of x = x^d mod N
Pick random d1 < N
d2 = (d - d1) mod N
x^d1 * x^d2 mod N = x^d mod N
- 2 people need to cooperate to sign
- Each piece (d1 and d2) looks random.
- d1 is a random number, and d2 is an unknown key minus d1
Learning one doesn't compromise the other, must get both
- Can split k ways: d - d1 - d2 ...
- Trick: real key = difference of random pieces. Need all pieces to get secret key
Both tricks (key split, long/short term keys) used in practice
Designed by friends, and is simple. SSL designed by committee, and is complex.
Purpose: allow secure login sessions, tunneled connection across untrusted network
Skip TCP/IP in this discussion (not interesting from security standpoint, just gets data reliably)
Assume server is "well-known", client is quasi-anonymous
Steps (high-level, will then discuss in more detail)
- client makes TCP connection to server port 22
- exchange version info ("SSH-2-OpenSSh_2.5.1")
- negotiate algorithms (crypto, compression options)
- run key exchange protocol
Algorithm negotiation: Each side sends lists of algs it knows, in preference order
- key exchange ("diffie-hellman-group1-sha1")
- server host key type (digital signature alg)
- encryption (each direction) ("3des-cbc")
- MAC (each direction) ("hmac-sha1")
- compression (each direction) ("zlib")
- good for shorter msgs, faster transmission
- removes patterns, better encryption
Can send "none" in any area, but not typical.
Also, each side sends 16 random bytes (so each msg is different... use described later)
There is a fixed alg. for combining prefs to choose algorithm.
- NOTE: there is no encryption at this point, there could be various attacks (man-in-the-middle, etc.). Someone could be messing with us. Later in protocol, go back and ensure msgs were not tampered with.
Standard Diffie-Hellman
- A sends g^a mod p
- B sends g^b mod p
- Secret key = sha1( g^ab mod p )
If no attacks, then A and B have same K
- Choose p, g (documented)
- Server computes a "session ID" H
- H = sha1( concat of all msgs sent/recvd so far || server's public key || K)
- H different every time protocol run (because of 16 random bytes)
- If one side "cheats" and doesn't randomize the 16 bytes, the other side still can (ensuring a different H)
- Detect tampering if hashes don't match (what server sent/rcvd different from what client sent/rcvd)
Key exchange protocol:
- Server sends (server's public key, server's signature on H).
- Signed with server's private key
- Client recomputes H, verifies signature (decrypts sig with server's public key)
- if hashes match, msgs not tampered
- [now: know there is no man-in-middle, msgs authentic. However, server could be impostor -- may not be connected to real server]
- Client validates server's public key (is it the right key for desired server?)
- Ideal approach: client gets server key in advance (calls up sys admin), tells it to client software. client software checks that keys are same
- Usual approach: verify that key is the same as last time. First time: cross fingers and hope. [When connect for first time, asked to "add key to host database..." cool, that's what the msg is for.]
- Clever: ideal approach doesn't work, but this gives some measure of security
- My note: security is about ease of use. People will do what is easiest, so make security easy.
- Vulnerable at certain times (if know many people will be logging on for first time, like start of freshman year)
[now: client has authenticated server. NOTE: server does NOT authenticate client]
Compute encryption keys: MAC keys, IVs, by hashing
- concatenation of K with various various constants
Exchange msgs saying "start using keys now." After this, begin sending encrypted msgs.
Have an encrypted conversation.
Redo key exchange periodically.
- Either side can request new key exch. at any time
- Recommended interval: 1 hour or 1GB of traffic, whichever first
- Each key exch. protected by previous key
- Still do Diffie-Hellman, and encrypt g^a mod p using old key
- If adversary records msgs and tries to break, has to break each key separately
[Already have secure host-to-host connection, want user-to-host]
Client snds request containing
- username
- authentication
- method-specific-data (such as passwd)
Auth methods
- passwd: send user's pw as method-specific data
- server verifies in any way it likes
- server may demand password change
- public key method
- user has private signing key
- server knows user's public key in advance (somehow... not specified in protocol)
- (example: public key in file /u/felten/.ssh/key.txt on server... file is read/write only by felten)
- protocol: client offers to use specific public key
- server okays that key (if server rejects, end connection)
- client signs H (session ID) w/ key.
- OK, b/c each H different due to 16 random bytes.
- client sends server signature.
- server verifies
Same trick: sign fresh H, has random number in it (the 16 random bytes). Use to make sure msgs not replayed.
Host-based method (for hosts that trust each other)
- Server knows client's public key in advance
- Protocol
- client sends username
- client signs concatentation of (H, username)
- server verifies signature
[Have secure user-to-host connection]
Want: multiple user-to-host conn
Make multiple logical connections
- Say "this data is for connection #17"
Like port numbers in TCP/IP... there aren't separate channels for the ports
- Packet says "This data is for port #22"
Like having a bunch of P.O. boxes at the post office. All mail goes through same channel, rcvrs only pick up msgs that are for them.