J'ai écrit un proxy d'interception dans Python 3 qui utilise une technique d'attaque man-in-the-middle pour inspecter et modifier les pages qui y transitent à la volée. Une partie du processus d '"installation" ou de configuration du proxy implique la génération d'un certificat "racine" qui doit être installé dans le navigateur et chaque fois qu'un nouveau domaine est touché via HTTPS via le proxy, le proxy génère un nouveau certificat de site à la volée (et met en cache tous les certificats générés sur le disque afin de ne pas avoir à générer de nouveaux certificats pour les domaines pour lesquels des certificats ont déjà été générés) signé par le certificat racine et utilise le certificat de site pour communiquer avec le navigateur. (Et, bien sûr, le proxy forge sa propre connexion HTTPS au serveur distant.Le proxy vérifie également la validité du certificat de serveur si vous êtes curieux.)Les certificats d'interception de proxy générés à la volée provoquent des erreurs de navigateur
Eh bien, cela fonctionne très bien avec le navigateur surf. (Et, cela pourrait être pertinent - à partir de quelques versions, au moins, le surf n'a pas vérifié/faire respecter la validité du certificat.) Je ne peux pas certifier si c'est le cas pour des versions plus récentes.) Mais, Firefox donne un Erreur SEC_ERROR_REUSED_ISSUER_AND_SERIAL sur la deuxième (et toutes les demandes HTTPS) faites à travers le proxy et Chromium (je n'ai pas testé avec Chrome proprement dit) donne NET :: ERR_CERT_COMMON_NAME_INVALID sur chaque demande HTTPS. Ceux-ci présentent évidemment un problème majeur lorsque j'essaie de parcourir mon proxy d'interception. La bibliothèque SSL que j'utilise est pyOpenSSL 0.14 si cela fait une différence.
En ce qui concerne l'erreur SEC_ERROR_REUSED_ISSUER_AND_SERIAL de Firefox, je suis sûr que je suis pas réutilisant des numéros de série. (Si quelqu'un veut vérifier mon travail, ce serait plutôt rad: cert.py - notez le "crt.set_serial_number (getrandbits (20 * 8))" sur la ligne 168.) L'émetteur du certificat racine ne change évidemment pas, mais ne devrait pas changer, non? Je ne suis pas sûr de ce que signifie exactement "émetteur" dans le message d'erreur si ce n'est pas l'émetteur du certificat racine. En outre, la boîte de dialogue "Afficher le certificat" de Firefox affiche des numéros de série complètement différents pour les différents certificats générés par le proxy. (Par exemple, j'en ai un généré pour www.google.com avec un numéro de série de 00: BF: 7D: 34: 35: 15: 83: 3A: 6E: 9B: 59: 49: A8: CC: 88: 01: BA: BE: 23: A7: AD et un autre généré pour www.reddit.com avec un numéro de série de 78: 51: 04: 48: 4B: BC: E3: 96: 47: AC: DA: D4 : 50: EF: 2B: 21: 88: 99: AC: 8C.) Donc, je ne suis pas vraiment sûr de ce que Firefox se plaint exactement.
Mon proxy réutilise la clé privée (et donc la clé publique/le module) pour tous les certificats qu'elle crée à la volée. J'en suis venu à penser que c'était ce que Firefox essayait de faire et j'ai essayé de changer le code pour générer une nouvelle paire de clés pour chaque certificat créé par le proxy à la volée. Cela n'a pas résolu le problème dans Firefox. Je reçois toujours le même message d'erreur. Je n'ai pas encore testé si cela résout le problème de Chromium.
En ce qui concerne l'erreur NET :: ERR_CERT_COMMON_NAME_INVALID de Chromium, le nom commun du certificat de site est supposé être le domaine, n'est-ce pas? Je ne devrais pas inclure un numéro de port ou quoi que ce soit, n'est-ce pas? (Encore une fois, si quelqu'un veut vérifier mon travail, voir cert.py.) Si cela aide, mon proxy intercepter n'utilise pas de caractères génériques dans les noms communs de certificat ou quoi que ce soit. Chaque certificat généré est pour un fqdn spécifique.
Je suis tout à fait certain de faire ce travail sans que Firefox ou Chrome (ou Chromium ou IE etc) soit possible. Une entreprise que je travaillais pour acheter et mettre en place un man-in-them-middling proxy à travers lequel tout le trafic à partir du réseau d'entreprise à l'Internet devait passer.Les administrateurs PC de cette société ont installé un certificat auto-signé comme autorité de certification dans chaque navigateur sur chaque ordinateur appartenant à l'entreprise utilisé par les employés et le résultat n'a jamais produit d'erreurs comme celles que Firefox et Chromium m'ont données pour les certificats. propre logiciel d'interception proxy produit. Il est possible que les administrateurs du PC en aient modifié quelques-uns sur: les paramètres de configuration dans Firefox pour que tout cela fonctionne ou quelque chose, mais j'en doute un peu. Pour être juste, le proxy utilisé dans cette entreprise était soit une couche de réseau ou de transport, pas une couche d'application comme la mienne. Mais je m'attendrais à ce que la même chose puisse être accomplie dans un proxy HTTP (s) de couche application. Editer: J'ai essayé de définir le subjectAltName comme suggéré par brain99. Voici la ligne que j'ajouté à l'emplacement brain99 suggéré:.
r.add_extensions([crypto.X509Extension(b"subjectAltName", False, b"DNS:" + cn.encode("UTF-8"))])
Je suis toujours obtenir SEC_ERROR_REUSED_ISSUER_AND_SERIAL de Firefox (sur la deuxième et les demandes ultérieures HTTPS et je reçois ERR_SSL_SERVER_CERT_BAD_FORMAT de chrome
Voici quelques certificats générés par le proxy:
google.com: https://pastebin.com/YNr4zfZu
stackoverflow.com : https://pastebin.com/veT8sXZ4
Le texte de prime Danged n'a pas conservé le formatage. Désolé pour le wall-o-text. – AntiMS
Vous devez utiliser subjectAltName au lieu de commonName. –
Partager deux certs que firefox prétend être réutilisés pourrait aider. –