1

对于 HTTPS 可访问服务的本地测试,我正在使用以下程序生成自己的密钥和证书。毫无疑问,该程序构建的证书在各种方面都不符合现实世界证书的最佳实践。但是,导致 Chrome 以这种“不符合安全标准”的错误拒绝它们的特定问题让我无法理解。

Chrome 报告的完整(较少域)错误是:

chrome很伤心,但我不知道为什么

生成证书、密钥等的程序是:

#!/usr/bin/env python

from __future__ import unicode_literals, print_function

from string import uppercase
from datetime import datetime, timedelta

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives.hashes import SHA256
from cryptography.hazmat.primitives import serialization
from cryptography.x509 import (
    CertificateBuilder,
    SubjectAlternativeName,
    BasicConstraints,
    DNSName,
    Name,
    NameAttribute,
)
from cryptography.hazmat.backends import default_backend

def cert(issuer, subject, issuer_key, subject_key, ca):
    builder = CertificateBuilder(
    ).issuer_name(
        Name([NameAttribute(NameOID.COMMON_NAME, issuer)]),
    ).subject_name(
        Name([NameAttribute(NameOID.COMMON_NAME, subject)]),
    ).add_extension(
        SubjectAlternativeName([DNSName(subject)]),
        critical=False,
    )
    if ca:
        builder = builder.add_extension(
            BasicConstraints(True, None),
            critical=True,
        )
    return builder.public_key(subject_key.public_key(),
    ).serial_number(1,
    ).not_valid_before(datetime.utcnow(),
    ).not_valid_after(datetime.utcnow() + timedelta(days=365),
    ).sign(issuer_key, SHA256(), default_backend(),
    )

def main(num_certs, subject_name):
    keys = tuple(
        rsa.generate_private_key(
            public_exponent=65537,
            key_size=1024,
            backend=default_backend(),
        )
        for i in range(num_certs)
    )

    names = list(
        ch + ".invalid"
        for ch
        in uppercase.decode("ascii")[:len(keys) - 1]
    ) + [subject_name]

    certs = tuple(
        cert(
            issuer=issuer_name,
            subject=subject_name,
            issuer_key=issuer_key,
            subject_key=subject_key,
            ca=is_ca,
        )
        for (issuer_name, subject_name, issuer_key, subject_key, is_ca)
        in zip(
            names[:1] + names[:-1],
            names,
            keys[:1] + keys[:-1],
            keys,
            range(len(keys) - 1, -1, -1),
        )
    )

    print("\n".join(
        key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption(),
        for key
        in keys
    ))

    print("\n".join(
        cert.public_bytes(serialization.Encoding.PEM)
        for cert
        in certs
    ))

main(3, "<some domain name>")

该程序吐出密钥,然后是证书。在链长度为 3 的默认设置下,有一个 CA 密钥/证书、一个中间密钥/证书和一个服务器密钥/证书。

这是它的输出示例:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCx5455hmlbJ/jWgZDuoPy6ymVSHarTOmSMYWp9jTae3Y5t7WEB
8mYdjW/3kZbr8+GVj2gSVHPdQMQdLMwgGmZKnG0VmiZsjHBBu3TA4ZymNGCppUPy
+z4stSEhLA+m0x8yAGt5qorbHcWo9rQnSXTtLD0RlGS4SUutxXaYF88sVwIDAQAB
AoGATvHsPW0x72uLdtTEFcCGpfUOhSP5HAa7e7f244P4iwLSI2HFPHHucorC9t86
U7ZDknSyv/+N8s68uB2a71wHq7JXwRzaU49sQk5NcPHgT5VjYPKtyL+0eY1hXqcn
zzIYRxtFAYiJXPa2ghKHBuP/tpMXMhIkMmMyfYJfd2a9YXECQQDlt7s010CvQcBu
wxa1riZUhp/a5MaaRPMJrJ0H8FFD34i953p0bddyyybSEyNpTfFTF42dfIAgLNDb
YeJj+wLTAkEAxkJA/F5TcXAxdEXtJgXU1zdzEfvrUFNfFR1Vf/Kzkr0618FqQZWL
lLHckqcqH4I+vdw2ycy7kpY0JDkRIBzV7QJAN5+WkAPzILy+GNPaYuGpXFxAxuMQ
h/hcFSKb33k8ZD/zP3CWgSy7t4sjekiyEWSTI7iXTOQBrkjLxeNcyzLTiwJAdHiV
vu0XLkxP8VPnNvA0Et9TbZxGqKDh+gCKqykEz871U60f5Dmbj5ZR06H7ABm/DEDj
uvfYtgwhw6n24puuHQJBAKSAxj+qsjRk8fK9J6GKZ+qaMNEQlzHdQH9LVjzlCSlP
r9GkzmdLnlfVPck3ytJhkgYWQgSE3eh45kGkDOkGZ8U=
-----END RSA PRIVATE KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDZPrkocPoakI93K2Z3pF8rHaq6L84ZG7o0UbWu5zgXc64PhBFU
xALTRbcGTVhIjViJKDue7iYq5/5TfGOXsF3gXxcXt5OQT9JN1t42T1FzuKxVwgg5
vXqjGFHLZJqBNCG6wGuD4R7/wPro7Pt3rVEMSt9tLvb+CF53LbTM0SyJFQIDAQAB
AoGACk8lrjueQsB1bmxK0oakVYF05pz6JMriDTWLb59dVA+TRP05bVJX5/q48r2c
4OSEPQ4BtksK2KJluUR/3WTrL3Ii562zmNYWAZ6BM+aBt/FZDQY01og4kLVnOfU+
NRyhOThogIvXLCiUMNTTixZ7wO7TYa0bJc0tLBr0Guwk5YkCQQD9gG06iV4P7EfI
hHwR6q6tjGs54UVCWras26iKvb9Kob9DWIR510NowUZ5ALVAyWT9mpJvZy4+E6I4
O6lugpfLAkEA22LSm7h+1Ck3kVQYwvKrG9XNSe7rgPYH6mWPogoAZxXO53K74Hih
h8ZG/+JmuQOA5TJf5N1xRAncr6cUjFSGnwJBAM0SzMozAEYPVg7PpnL0EDVTSBb9
twKz0d3KoPEECTD94nU/sYPDccPXvwP6X6a2hZ1nIxk+Njl/tpaZJTrCKLsCQEvf
78sfke26m5dNqIqz9u3XkfqCAT1G2hH9MiHup5j/d+GgUs4dqnAU6TVSjghq58dd
FsFGvQe1CXhOptKp4S0CQQDy5yZ3qmtLhtGfO+c84skkxjcnwHwSR82tbBWaBpqo
tC2UYL7MrXBoNF/bgES+DKF5AdUqHyU6ecU0oq4eVY2f
-----END RSA PRIVATE KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC4fK/bPNx/M5lu0EL5iwFYB2wy+gpgBrnj77IRoDrtrOyBIiOa
LN+iBzxuINflFX+dFPqLGEc15Kuxe+HyZZDG9XOFt3qZ/0ijoi/x7BB1ZaNxGsF+
Tj4HAvEKKYjUz54cjnhDpt5ZOcJXbAYMNIODBMJJX8Ghg+K7whBQnqFSFQIDAQAB
AoGAIE7NqTI2VxxdMVfNctASEy1xmFfLe1eSNEWkxItv5nGTFWY6H+Td4Q0tWwfr
ZxXlvEeRPMyqo9iA7NsKDZ4VxUW1VBw8Cw4Ua5RDtsRZUL9wc16Wk0y5pwCjWDrP
DI8yRBGmtx+5uY0CNeYQ0mQA1SHC9KtrDRC2kHIDfYN3nh0CQQDmc5/nBV0RTjKs
EdeiRlhAuwEC2zwNQYF/xZzfL9PS65t13Rm1mW2G75RMrjFJclXe+y/SdAibYNJi
lucSsckLAkEAzPCOOvxKjjXTeCyfc1fAYZMOhz/oMy4t+qy2Yc6Lp6DJrhR3T3JC
9qjaLh2a+OnwIPrn5EGQWSLXlSSHNr+FXwJAWWV7HzQ+cSsjjwpw2tts+tdQQhpn
xkCmCrnO6+lyw3xwVx2JDqBRE6o2njRonDRFSXWpjHtEp3m8w1AEnYToFwJAfVFf
98vMn1dkv6ixvCtdtYziJmw6xgkoDpBMWlSd61wT14ImTwt0zTYFbIun9yu+Lbyf
zmEVLpxyrX2PvTeyCwJAP1bQmjTVTMv1ahn9QvarbsqlOV3lMbiyfHREVAGON9LA
e8UCAlL1u0RuV2lqhK8rlkMqxUuZ/D6uDlLrTJpCew==
-----END RSA PRIVATE KEY-----

-----BEGIN CERTIFICATE-----
MIIByjCCATOgAwIBAgIEWVRCgjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlB
LmludmFsaWQwHhcNMTcwNjI4MjM1NzU0WhcNMTgwNjI4MjM1NzU0WjAUMRIwEAYD
VQQDDAlBLmludmFsaWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALHnjnmG
aVsn+NaBkO6g/LrKZVIdqtM6ZIxhan2NNp7djm3tYQHyZh2Nb/eRluvz4ZWPaBJU
c91AxB0szCAaZkqcbRWaJmyMcEG7dMDhnKY0YKmlQ/L7Piy1ISEsD6bTHzIAa3mq
itsdxaj2tCdJdO0sPRGUZLhJS63FdpgXzyxXAgMBAAGjKTAnMBQGA1UdEQQNMAuC
CUEuaW52YWxpZDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBADfL
MQitgG+iFEraLMoXzkO65T1JnKIY4rnpW6bJP0Mt2PaSCzvH3AlPnA7ZGvw+x5+b
EdhaxiY3sweSfbRaYubhDHaL8lNB0So4SP1hVFNFQjSLR1aGqoeqY7IYhIzpQ5MK
Pb+sYmvdko45431t8GJOkb9Pg7N/o1aRfzCK2Lca
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIByjCCATOgAwIBAgIEWVRCgjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlB
LmludmFsaWQwHhcNMTcwNjI4MjM1NzU0WhcNMTgwNjI4MjM1NzU0WjAUMRIwEAYD
VQQDDAlCLmludmFsaWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANk+uShw
+hqQj3crZnekXysdqrovzhkbujRRta7nOBdzrg+EEVTEAtNFtwZNWEiNWIkoO57u
Jirn/lN8Y5ewXeBfFxe3k5BP0k3W3jZPUXO4rFXCCDm9eqMYUctkmoE0IbrAa4Ph
Hv/A+ujs+3etUQxK320u9v4IXncttMzRLIkVAgMBAAGjKTAnMBQGA1UdEQQNMAuC
CUIuaW52YWxpZDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBADTP
BSezJqx9+7MZVqLcFz0K5K9NsVr5NRn8naC/W8mDNaSet4aeHLWZgVHwMZAiRka8
aAPYwoqXjjjS1/0Z/+eag24D81g2JvSk0t9dB44OCFfq2sgm1ERP0UW5BUKTf2iJ
WyOLpoMVFAeVqp4wug3IcWOOv8JAXmq9oAwlT92g
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIB0TCCATqgAwIBAgIEWVRCgjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlC
LmludmFsaWQwHhcNMTcwNjI4MjM1NzU0WhcNMTgwNjI4MjM1NzU0WjAgMR4wHAYD
VQQDDBVzdGFja292ZXJmbG93LmludmFsaWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
MIGJAoGBALh8r9s83H8zmW7QQvmLAVgHbDL6CmAGuePvshGgOu2s7IEiI5os36IH
PG4g1+UVf50U+osYRzXkq7F74fJlkMb1c4W3epn/SKOiL/HsEHVlo3EawX5OPgcC
8QopiNTPnhyOeEOm3lk5wldsBgw0g4MEwklfwaGD4rvCEFCeoVIVAgMBAAGjJDAi
MCAGA1UdEQQZMBeCFXN0YWNrb3ZlcmZsb3cuaW52YWxpZDANBgkqhkiG9w0BAQsF
AAOBgQBGj3dezNMMzE4PqkojXkenqKD6NlksldpRL3TOVAXCK6L0NciJbQcxi/9W
zfcaVQBGvNjmg6ieNYCamF+Fz/hg+m4pTrKLy54UnyOa8gUTg+tPJuJHO2FsdeOm
tbgQKLrqpBUJX4+SzEMQYzZfPhOj29SzItCDeRjYhn0m7Otp/Q==
-----END CERTIFICATE-----
4

1 回答 1

2

所有这三个证书都具有完全相同的序列号 (0x59544282)。Chrome 不喜欢这样——您需要为您的 CA 签署的每个证书使用唯一的序列号。

于 2017-06-29T00:27:57.917 回答