一个自签名证书来管理他们所有人?Chrome、Android和iOS

一个自签名证书来管理他们所有人?Chrome、Android和iOS,android,ios,google-chrome,openssl,certificate,Android,Ios,Google Chrome,Openssl,Certificate,还有一个自签名证书的问题,但我已经尝试了几天,以找到创建自签名证书的最佳/正确方法,该证书将在我最新版本的Chrome、Android和iOS的开发环境中工作 我在这里和其他地方找到的说明对于其中至少一个平台来说已经过时了 这是我找到的最好的,但它只适用于Chrome和Android openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/C=US/ST=Oklahoma/L=Stillwater/O=My Compan

还有一个自签名证书的问题,但我已经尝试了几天,以找到创建自签名证书的最佳/正确方法,该证书将在我最新版本的Chrome、Android和iOS的开发环境中工作

我在这里和其他地方找到的说明对于其中至少一个平台来说已经过时了

这是我找到的最好的,但它只适用于Chrome和Android

openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/C=US/ST=Oklahoma/L=Stillwater/O=My Company/OU=Engineering" -keyout ca.key -out ca.crt
openssl genrsa -out "test.key" 2048
openssl req -new -key test.key -out test.csr -config openssl.cnf
openssl x509 -req -days 3650 -in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extensions v3_req -extfile openssl.cnf -out test.crt
openssl x509 -inform PEM -outform DER -in test.crt -out test.der.crt
openssl.cnf的内容:

[req]
default_bits = 2048
encrypt_key  = no # Change to encrypt the private key using des3 or similar
default_md   = sha256
prompt       = no
utf8         = yes

# Specify the DN here so we aren't prompted (along with prompt = no above).

distinguished_name = req_distinguished_name

# Extensions for SAN IP and SAN DNS

req_extensions = v3_req

# Be sure to update the subject to match your organization.

[req_distinguished_name]
C  = US
ST = Oklahoma
L  = Stillwater
O  = My Company
OU = Engineering
CN = test.com

# Allow client and server auth. You may want to only allow server auth.
# Link to SAN names.

[v3_req]
basicConstraints     = CA:TRUE
subjectKeyIdentifier = hash
keyUsage             = digitalSignature, keyEncipherment
extendedKeyUsage     = clientAuth, serverAuth
subjectAltName       = @alt_names

# Alternative names are specified as IP.# and DNS.# for IP addresses and
# DNS accordingly.

[alt_names]
DNS.1 = test.com
在我的开发服务器上安装test.crt和test.key之后,这种方法对Chrome非常有效:只需将test.crt添加到Mac的钥匙链中,并为其启用“始终信任”

它也适用于Android:通过电子邮件将test.der.crt发送到设备并点击安装。最重要的是:它显示在设置/加密和凭据/可信凭据下的“用户”选项卡中。这对于在我的Android应用程序中使用是必不可少的

不幸的是,它不适用于iOS:

  • 我通过将证书拖到Xcode模拟器中安装了它
  • 我必须同时安装test.crt和ca.crt。如果我只是安装了test.crt,它仍然处于“未验证”状态,这是有意义的,因为ca.crt是根证书
  • 它没有显示在“设置”/“关于”/“证书信任设置”下,这是我打开它所必需的
  • 当我的应用程序尝试使用NSMutableURLRequest访问我的服务器时,它会收到一个包含10个键值对的“TIC SSL信任错误”,包括:
    • NSURLERRORFAILINGURLPERTRUSTERRORKEY=
    • _kCFStreamErrorDomainKey=3
    • _kCFStreamErrorCodeKey=-9813
    • NSErrorPeerCertificateChainKey=1元素,NSLocalizedDescription=此服务器的证书无效。您可能正在连接假装为“test.com”的服务器,这可能会使您的机密信息处于危险之中
知道如何更改我所做的,以便在“证书信任设置”下为iOS打开它吗

注1:由于关于-9813错误代码的其他问题的其他答案表明可能缺少中间证书,因此我将ca.crt添加到我的Apache配置中,用于SSLCaCertificateFile设置。它在Chrome和Android上仍然运行良好,但在iOS上也有同样的错误


谢谢

此答案已更新(并简化)为与iOS 13和Android 8兼容。用户回答:fixitnowyes将于2019年10月6日生效

只需一个openssl命令即可创建在Chrome、Android和iOS中运行的自签名证书:

openssl req -config openssl.cnf -new -x509 -days 825 -out ca.crt
这将输出ca.crt和ca.key。请注意,825天是iOS 13+允许的最大持续时间,必须在openssl命令中指定。openssl.cnf中的days设置没有做任何我能说的事情

通过以下方式检查有关证书的信息:

openssl x509 -in ca.crt -text -noout
openssl.cnf的内容

[ req ]
default_bits        = 2048
default_keyfile     = ca.key
default_md          = sha256
default_days        = 825
encrypt_key         = no
distinguished_name  = subject
req_extensions      = req_ext
x509_extensions     = x509_ext
string_mask         = utf8only
prompt              = no

# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
#   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.

[ subject ]
countryName                 = US
stateOrProvinceName         = Oklahoma
localityName                = Stillwater
organizationName            = My Company
OU                          = Engineering

# Use a friendly name here because it's presented to the user. The server's DNS
#   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
#   by both IETF and CA/Browser Forums. If you place a DNS name here, then you
#   must include the DNS name in the SAN too (otherwise, Chrome and others that
#   strictly follow the CA/Browser Baseline Requirements will fail).

commonName              = test.com
emailAddress            = me@home.com

# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...

[ x509_ext ]
subjectKeyIdentifier      = hash
authorityKeyIdentifier    = keyid:always,issuer

# You only need digitalSignature below. *If* you don't allow
#   RSA Key transport (i.e., you use ephemeral cipher suites), then
#   omit keyEncipherment because that's key transport.

basicConstraints        = critical, CA:TRUE
keyUsage            = critical, digitalSignature, keyEncipherment, cRLSign, keyCertSign
subjectAltName          = DNS:test.com
extendedKeyUsage = serverAuth

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.

extendedKeyUsage    = TLS Web Server Authentication

# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...

[ req_ext ]
subjectKeyIdentifier        = hash
basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = DNS:test.com
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage    = serverAuth, clientAuth

# [ alternate_names ]
# DNS.1       = example.com
# DNS.2       = www.example.com
# DNS.3       = mail.example.com
# DNS.4       = ftp.example.com


# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1
创建证书后

服务器安装:

  • 在服务器中安装ca.crt和ca.key
  • 重新启动服务器
  • Chrome/Safari安装:

  • 将ca.crt添加到系统钥匙链(或同等PC)中Mac的钥匙链访问中
  • 将其设置为“始终信任”(在Mac中),以便在Chrome和Safari中工作
  • iOS安装:

  • 将ca.crt拖到模拟器上。至少在Xcode 12中是这样的。请注意,没有确认发生了任何事情
  • 应该不需要转到设置/常规/关于/证书信任设置并启用它。它应该已经启用
  • 如果上述方法不起作用,您可以通过向自己发送ca.crt文件,登录模拟器中的Mail应用程序,然后从那里打开它来找出原因

    安卓安装:

  • 将ca.crt发送到您的Gmail帐户,然后在您的邮箱中登录Gmail Android模拟器,点击安装
  • 它应该出现在“用户”选项卡的“设置/锁屏和安全性/加密和凭据/受信任凭据”下

  • 我会在没有DNS的情况下测试OsX。2=localhost以了解这是否是它被忽略的原因,因为与移动平台相比,它们在不安全的本地服务器上存在更多问题。感谢您的建议。我从一开始就在没有localhost的情况下重播了所有步骤,但在iOS上仍然存在相同的问题。我已经在上面的原始问题中提供了更多的细节。我终于找到了我上面的说明中的错误,导致证书无法在iOS中工作。第一步中的“sub”参数需要包含CN(公共名称),该值等于openssl.cnf文件中给定的值。我会在我的回答中详细说明。有没有办法说“信任此根CA及其所有子项”,而不是手动添加每个域证书?我在macOS上成功地将ca.crt添加到keychain并将其标记为可信,但在Android上似乎不起作用:ca.crt即使在成功添加之后也不会出现在“用户”选项卡上(domain.crt会出现)。在真正的Andriod设备上,移动chrome的过程是什么?在哪里放置我的ca.cert?它应该与模拟器的过程相同。通过电子邮件将其发送给您自己,并从设备登录到您的电子邮件帐户,然后点击它。你也可以把它放在谷歌硬盘上,然后在设备上打开它。感谢上帝,你已经搜索了几个小时了。。。我不知道为什么在每台设备上工作都这么复杂