Firefox 使用相同的自签名CA编码多个证书?

Firefox 使用相同的自签名CA编码多个证书?,firefox,ssl,proxy,openssl,self-signed,Firefox,Ssl,Proxy,Openssl,Self Signed,我正在编写一个拦截代理来监视从浏览器发送的请求。使用https,我要做的是: 当浏览器发出连接请求时,代理将连接到该主机并获取其证书。 然后,使用此证书的subject和subjectAltName动态生成一个新证书,该证书将呈现给浏览器以建立与代理的SSL连接 所有这些新证书都具有根自签名证书作为颁发者。 根证书已作为受信任的证书导入Firefox 但是,当我尝试连接时,仍然会收到不受信任的连接警告,并显示以下详细信息: www.google.com uses an invalid secur

我正在编写一个拦截代理来监视从浏览器发送的请求。使用https,我要做的是: 当浏览器发出连接请求时,代理将连接到该主机并获取其证书。 然后,使用此证书的subject和subjectAltName动态生成一个新证书,该证书将呈现给浏览器以建立与代理的SSL连接

所有这些新证书都具有根自签名证书作为颁发者。 根证书已作为受信任的证书导入Firefox

但是,当我尝试连接时,仍然会收到不受信任的连接警告,并显示以下详细信息:

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)
我使用的浏览器是Firefox28.0。我还不太明白为什么连接结果不可信,因为我已经安装了根证书。现在,我必须为我访问的每个网站添加一个例外,坦白说,这很烦人,而且会减慢一切

我正在使用pyOpenSSL生成证书。 我用来制作根证书的代码是:

    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))
然后,我使用类似的代码生成特定于域的证书。现在,我正在使用一个只使用谷歌的例子,尽管我一解决这个问题就会使用一些缓存系统

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
我似乎没有在这里找到主要的bug,当我查看创建的证书时,它正确地将我自己的证书根作为颁发者。不过,浏览器说它不可信。如果我把它作为一个例外添加,它是有效的,但对于一些网站,我甚至没有这个选项,我唯一能做的就是查看详细信息并单击“让我离开这里”


问题可能在代码中吗?或者这是配置浏览器的问题?

如果您的CA证书已作为受信任的CA导入Firefox,它应该可以工作

“该证书不受信任,因为它是自签名的。”和“该证书仅对MyApp CA根有效”表示您显然没有提供您认为是的服务器证书


这可能只是代码中的一个错误,您发送了错误的证书,也可能是您以错误的顺序发送了链:CA证书优先,而最终实体证书应优先(然后是其CA,以签名顺序)。

我在代码中发现了一个错误(我使用根证书而不是其他生成的证书进行连接)。但我仍然收到一个错误。我用新的问题编辑了该问题。您可能没有将CA证书正确导入浏览器,或者您没有使用正确的颁发者生成证书。您是否检查了时间有效性?可能您的代理和客户端设置的时间不完全相同。我会调整n例如,otBefore的值为负值。已检查。仍然存在错误。鉴于我现在要格式化pc,我将查看这是否与浏览器有关。尝试将密钥大小增加到2048可能:我在这里询问,因为这可能是程序逻辑中的一个错误,或者可以通过处理代码而不是e浏览器。@jww有一点,就目前的主题而言,它实际上处于边缘。在的上下文中,它可能在主题上,但需要更多关于您实际代码的详细信息。到目前为止,它看起来仍然像是一个“修复我的错误”类型的问题,几乎没有什么可继续的。您对该问题的编辑也使现有答案难以回答(因为它不再真正匹配),而且以后其他人也不会对它感兴趣。请改进您的问题…好的,谢谢您的建议。我将在使用合适的pc后立即编辑。
cert.get_subject().CN='MyApp Root CA'…
-+1,用于在
CN
中使用友好名称,并将DNS名称放置在
SAN
中“…但是,我在尝试连接时仍然收到不受信任的连接警告…”-我们需要查看
openssl s_客户端-tls1-连接google.com:443-servername google.com
的输出。确保使用DNS技巧,以便google.com解析到您的代理。您甚至可以使用SNI来欺骗/避免DNS:
openssl s_客户端-tls1-连接:-servername google.com