2014-06-30 1 views
1

J'écris un proxy d'interception pour surveiller les demandes envoyées par mon navigateur. Avec https, ce que je fais est: lorsque le navigateur fait une demande CONNECT, le proxy se connecte à cet hôte et obtient son certificat. Ensuite, le subject et subjectAltName de ce certificat sont utilisés pour générer un nouveau certificat à la volée, qui est présenté au navigateur pour établir une connexion SSL avec le proxy.Codage de plusieurs certificats avec la même autorité de certification auto-signée?

Tous ces nouveaux certificats ont comme émetteur un certificat racine auto-signé. Le certificat racine a déjà été importé comme approuvé dans Firefox.

Pourtant, je reçois toujours un avertissement de connexion non fiable lorsque je tente de se connecter et les détails suivants:

www.google.com uses an invalid security certificate. 
The certificate is not trusted because the issuer certificate is not trusted. 
(Error code: sec_error_untrusted_issuer) 

Le navigateur J'utilise Firefox est 28,0. Je n'ai pas bien compris pourquoi les résultats de connexion ne sont pas fiables, vu que j'ai installé le certificat racine. En ce moment, je devrais ajouter une exception pour chaque site que je visite, ce qui est franchement très ennuyeux et ralentit tout. J'utilise pyOpenSSL pour faire des certificats. Le code que je fabriquais le certificat racine est:

from OpenSSL import crypto 
    CERT_FILE = 'myapp.pem' 
    KEY_FILE = 'myapp.key' 
    k = crypto.PKey() 
    k.generate_key(crypto.TYPE_RSA, 1024) 

    cert = crypto.X509() 
    cert.get_subject().O = "Myapp" 
    cert.get_subject().OU = 'MyApp Root CA' 
    cert.get_subject().CN = 'MyApp Root CA' 
    cert.set_serial_number(888) 
    cert.gmtime_adj_notBefore(0) 
    cert.gmtime_adj_notAfter(10*365*24*60*60) 
    cert.set_issuer(cert.get_subject()) 
    cert.set_pubkey(k) 
    cert.sign(k, 'sha1') 

    with open(CERT_FILE, "wt") as cf: cf.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) 
    with open(KEY_FILE, "wt") as kf: kf.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k)) 

Ensuite, j'utiliser un code similaire pour générer des certificats spécifiques au domaine. En ce moment je travaille avec un exemple en utilisant seulement Google, bien que je vais utiliser un système de mise en cache dès que je résous cela.

root_cert = crypto.load_certificate(crypto.FILETYPE_PEM, 'myapp.pem') 
root_key = crypto.load_privatekey(crypto.FILETYPE_PEM, 'myapp.key') 
root_issuer = root_cert.get_issuer() 

def make_example_cert(pem_data): 
    if os.path.exists('google.pem'): return #ugly hack to avoid remaking file 
    #load the certificate received from google 
    old_cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_data) 
    #generate new key and certificate 
    pkey = crypto.PKey() 
    pkey.generate_key(crypto.TYPE_RSA, 1024) 
    new_cert = crypto.X509() 
    new_cert.gmtime_adj_notBefore(0) 
    new_cert.gmtime_adj_notAfter(10*365*24*60*60) 
    #set same subject of old cert 
    new_cert.set_subject(old_cert.get_subject()) 
    #look for and set SNA of old cert 
    for i in range(old_cert.get_extension_count()): 
      ext = old_cert.get_extension(i) 
      if ext.get_short_name() == 'subjectAltName': 
       new_cert.add_extensions([ext]) 
    #set root certificate as issuer 
    new_cert.set_issuer(root_issuer) 
    new_cert.set_pubkey(pkey) 
    new_cert.sign(root_key, 'sha1') 
    certfile = 'google.pem' 
    keyfile = 'google.key' 
    with open(certfile, "wt") as cf: 
     cf.write(crypto.dump_certificate(crypto.FILETYPE_PEM, new_cert)) 
    with open(keyfile, "wt") as kf: 
     kf.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)) 
    #append root certificate to chain 
    with open(certfile, "at") as cf2: 
     cf2.write(crypto.dump_certificate(crypto.FILETYPE_PEM, root_cert)) 

    return certfile, keyfile 

Je ne semble pas trouver des bugs majeurs ici, et quand je considère le certificat créé correctement a ma propre certificat racine comme émetteur. Pourtant, le navigateur dit qu'il n'est pas fiable. Cela fonctionne si je l'ajoute comme une exception, mais pour certains sites Web, je n'ai même pas cette option et la seule chose que je peux faire est de voir les détails et de cliquer sur "Sors-moi d'ici".

Le problème est peut-être le code? Ou s'agit-il de configurer le navigateur?

+0

J'ai demandé ici parce que cela peut aussi bien être une erreur dans la logique du programme, ou il pourrait être réparé en travaillant sur le code plutôt que sur le navigateur. – user3725459

+0

@jww a un point, c'est vraiment limite sur le sujet en l'état. Il pourrait être sur le sujet, dans le contexte de [votre question précédente] (http://stackoverflow.com/q/24325367/372643), mais il devrait y avoir plus de détails sur votre code actuel. Jusqu'à présent, il ressemble toujours à un type de question «réparer mon bug» avec peu de choses à faire. Votre modification à cette question rend également les réponses existantes difficiles à trouver (puisqu'elles ne correspondent plus vraiment), et il est peu probable qu'elles intéressent quelqu'un d'autre à l'avenir. S'il vous plaît améliorer votre question ... – Bruno

+0

Ok, merci pour les suggestions. Je vais l'éditer dès que je serai sur un bon PC. – user3725459

Répondre

3

Si votre certificat CA a été importé dans Firefox comme une autorité de certification approuvée, cela devrait fonctionner.

« Le certificat est pas digne de confiance parce qu'il est auto-signé. » et « Le certificat est valable uniquement pour MyApp CA racine » indique que vous êtes visiblement pas au service des certificats de serveur que vous pensez que vous êtes. Soit c'est un simple bogue dans votre code que vous envoyez le mauvais certificat, ou peut-être que vous envoyez la chaîne dans le mauvais ordre: CA cert en premier, alors que le certificat d'entité finale devrait être le premier (suivi par ses CA, dans la commande de signature).

+0

J'ai trouvé un bug dans le code (je me connectais en utilisant le certificat racine au lieu des autres certificats générés). Je reçois toujours une erreur cependant. J'ai édité la question avec le nouveau. – user3725459

+0

Vous n'avez probablement pas importé ce certificat d'autorité de certification dans votre navigateur correctement, ou vous n'avez pas généré vos certificats avec l'émetteur correct. – Bruno

+0

Avez-vous vérifié la validité de l'heure? Il est possible que votre proxy et vos clients ne soient pas définis exactement au même moment. J'ajusterais le notBefore avec une valeur négative, par exemple. – Bruno

Questions connexes