A friend insists it does, that both browser and server both need certificates. I say no, only the server requires one, with two keys. The question is whether the browser uses some sort of certificate (not just key) for encryption in SSL/TLS comms with the server.
The typical case of certificates issued by a trusted party (Let's Encrypt etc)
Server certificates are essential because the client needs to verify that it speaks with the expected server in order to detect man in the middle attacks. To authenticate itself against a client the server needs for this the certificate itself which is public and the private key matching the certificate which is only known to the server. To accept a server provided certificate as trusted the client will then among other things check if this certificate was issued by a trusted party, i.e. a trusted CA (CA meaning certificate authority, i.e. the entity which issues certificates). These trusted CA are stored as certificates in the trust store of the clients operating system or browser. These are the kind of certificates needed on the client side.
And then there are client certificates which are used to authenticate the client against the server. These are optional and used only rarely. If these are used the client not only needs the (public) certificate itself but also the matching secret private key, similar to what the server needs to authenticate itself against the client.
The uncommon case of self-signed server certificates
In this case the server sends a certificate which is not issued by a CA known to the browser (or app or other client). In this case no certificate is involved at the client side but the client needs to find another way to check if the certificate is the expected one. Typically the browser asks the user to add an exception in this case.
The even more uncommon case of no certificates at all
SSL/TLS can also be used without certificates at all, i.e. not even at the server side. In this case authentication is done with other methods, like a secret key pre-shared between client and server (PSK). These methods are rarely used and browsers don't support these.
Let's take a look at what happens between the server and client with SSL. From Wikipedia:
[T]hey negotiate a stateful connection by using a handshaking procedure. [...] During this handshake, the client and server agree on various parameters used to establish the connection's security:
- The handshake begins when a client connects to a TLS-enabled server requesting a secure connection and the client presents a list of supported cipher suites (ciphers and hash functions).
- From this list, the server picks a cipher and hash function that it also supports and notifies the client of the decision.
- The server usually then sends back its identification in the form of a digital certificate. The certificate contains the server name, the trusted certificate authority (CA) that vouches for the authenticity of the certificate, and the server's public encryption key.
- The client confirms the validity of the certificate before proceeding.
- To generate the session keys used for the secure connection, the client either:
- encrypts a random number with the server's public key and sends the result to the server (which only the server should be able to decrypt with its private key); both parties then use the random number to generate a unique session key for subsequent encryption and decryption of data during the session
- uses Diffie-Hellman key exchange to securely generate a random and unique session key for encryption and decryption that has the additional property of forward secrecy: if the server's private key is disclosed in future, it cannot be used to decrypt the current session, even if the session is intercepted and recorded by a third party.
This concludes the handshake and begins the secured connection, which is encrypted and decrypted with the session key until the connection closes.
At no point does the server ask the client for a certificate. Usually, in step 4 (confirming the validity of the certificate), the client uses a local store of CA certificates to verify that the certificate chain presented by the server is valid. However, it is entirely possible for the client to use some other method. For example, this is what happens with self-signed certificates: your browser will ask you if you want to accept this certificate which cannot be verified, and if you confirm, it happily goes on to finish the handshake. Command-line clients like
wget have options to indicate that you don't want to verify the certificate chain.
The client does not need to have certificates, but it's good practice to verify who the server says they are, and that means the client needs CA certificates to verify the certificate chain presented by the server.
It is possible to configure the server to ask for a client authentication certificate. See this MSDN post for an illustration.
TLS can work without any "TLS" certificate (that it truely a X.509 certificate in fact), this is orthogonal. One endpoint can have a certificate, or both, or none at all. TLS provide different benefits, authentication is only one of them (but the most important one in fact, over confidentiality which is often counterintuitive)