The confusion stems from applying the lockbox analogy too literally. In SSH authentication, we're not just encrypting messages - we're establishing mutual trust between client and server. The server stores client public keys for identity verification, not just encryption.
During SSH key-based authentication:
Client (private key) -> Signs challenge -> Server verifies with stored public key
Server (private key) -> Signs host key -> Client verifies on first connection
This two-way verification explains why both sides need each other's public keys, but in different ways.
Here's what happens when you add your public key to a server's authorized_keys:
# Client side generates keys
ssh-keygen -t ed25519
# Server stores public key in
~/.ssh/authorized_keys
The server uses this stored public key to verify that the client possesses the matching private key during login attempts.
Servers do have their own key pairs (host keys) that clients store in known_hosts. This serves a different purpose - verifying server identity to prevent MITM attacks.
Here's how OpenSSH actually verifies client keys (simplified):
// Server-side verification pseudocode
bool verify_client_signature(public_key, signature, challenge) {
return openssl_verify(
public_key,
signature,
challenge
);
}
Storing client public keys on servers allows:
- Centralized management of authorized users
- Revocation by simply removing the public key
- No need to distribute server keys to clients for authentication
The lockbox analogy breaks down because:
- SSH authentication isn't just about encrypting messages
- Both parties need to verify each other's identity
- The "direction" of trust establishment differs from the analogy
In SSH (Secure Shell) protocol, the server storing client public keys might seem counterintuitive at first glance when compared to other public-key cryptography implementations. However, this architecture serves a distinct purpose in the authentication workflow.
The typical sequence:
1. Client initiates connection: ssh user@server
2. Server checks ~/.ssh/authorized_keys for client's public key
3. Server challenges client to prove ownership of private key
4. Client signs a random value with private key
5. Server verifies signature using stored public key
Three core reasons explain this design:
- Authentication Direction: Unlike the lockbox analogy where Bob encrypts for Alice, SSH authenticates the client to the server
- Access Control: Storing public keys on servers allows sysadmins to manage authorized users through authorized_keys files
- Protocol Efficiency: Eliminates the need for certificate authorities in basic implementations
Here's how to inspect authorized_keys on a Linux server:
# View authorized keys for current user
cat ~/.ssh/authorized_keys
# Sample entry format:
ssh-rsa AAAAB3NzaC1yc2E... comment@client-machine
The server-side public key storage creates important security considerations:
# Recommended permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
This prevents unauthorized modifications while allowing SSH daemon access.
Protocol | Public Key Location | Authentication Flow |
---|---|---|
SSH | Server | Client → Server |
TLS | Client | Server → Client |
PGP | Key Servers | Peer-to-peer |