J'appelle une URL HTTPS via un programme Java. Mon client Java doit-il fournir un certificat au serveur pour établir cette connexion? En d'autres termes, ai-je besoin de mon propre certificat ou le certificat du serveur (qui contient sa clé publique) est-il suffisant?
Cela dépend de ce que vous faites et de ce que vous voulez vérifier. Si vous accédez à des données et que vous souhaitez vous assurer que le serveur qui connaît la clé privée correspondante est celui qui vous envoie des données (par exemple, vous accédez à une page Web), vous n'avez pas besoin de votre propre certificat.
Si le serveur veut pouvoir vérifier que le client est un client prédéfini, qui connaît une clé privée correspondant à une clé publique reconnue comme source valide, votre client aura besoin d'un certificat. Cela a tendance à être utilisé lorsqu'une paire de serveurs communique - ils signent chacun les données avec leur propre clé privée et peuvent vérifier que les données proviennent d'une source connue en vérifiant les clés publiques. Il peut également être utilisé avec certaines API, où seuls des clients spécifiques sont destinés à accéder.
Par conséquent, vous n'avez pas besoin de votre propre certificat pour votre client - il est généralement assez bien documenté par le serveur si vous le faites.
Généralement, la plupart des serveurs Web exécutant HTTPS ne nécessitent pas que le client possède un certificat. Si le serveur requiert que le client s'authentifie, cela se fait souvent via des informations d'identification (par exemple, nom d'utilisateur et mot de passe).
Cependant, l'inverse n'est généralement pas vrai - c'est-à-dire que la plupart des clients nécessitent que les serveurs Web aient un certificat valide signé par une autorité de certification reconnue. Il est de la responsabilité du client de vérifier que le certificat est valide - sinon le client n'a aucun moyen de s'assurer qu'il est bien connecté au serveur auquel il avait l'intention de se connecter et qu'il n'est pas MITM.
Non, je l'ai essayé et le client n'a certainement pas besoin d'un certificat ou d'une clé prédéfinie.
Au lieu de cela, après avoir reçu une clé publique (qui fait partie du certificat) du serveur, le client crée un secret "à la volée" et le chiffre avec la clé publique du certificat du serveur. Le client envoie le secret chiffré au serveur dans le cadre de la prise de contact. Seul le serveur peut décrypter le message contenant le secret du client tant que seul le serveur possède la clé privée correspondant à la clé publique qu'il a envoyée dans le certificat. Le client et le serveur utilisent ensuite le secret transmis en toute sécurité pour poursuivre la conversation.
Les clés client ne sont nécessaires que lorsque le serveur doit confirmer l'identité du client; dans ce cas, le client et le serveur peuvent communiquer en transmettant à la place des messages chiffrés avec leurs clés publiques respectives.
Vous pouvez le voir en action en exécutant votre code avec l'option jvm suivante:
Djavax.net.debug = ssl, poignée de main
Le client et le serveur peuvent convenir d'un certain nombre de systèmes de chiffrement différents pour échanger puis utiliser le secret inventé; sur mon banc d'essai, il était par défaut le cryptage Elliptic Curve, comme décrit à
https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art06