一张自签名证书可以统治所有这些?Chrome,Android和iOS

Sco*_*tyB 3 android openssl google-chrome certificate ios

另一个自签名证书问题,但是我已经尝试了几天,以找到创建自签名证书的最佳/正确方法,该方法将在我的开发环境中适用于最新版本的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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在我的开发服务器上安装了test.crt和test.key之后,此方法对Chrome十分有效:只需将test.crt添加到Mac的钥匙串中,然后为其打开“始终信任”即可。

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

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

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

知道如何更改我的操作,以便可以在“证书信任设置”下为iOS打开它吗?

注意1:由于对有关-9813错误代码的其他问题的其他答案表明可能缺少中间证书,因此我在Apache配置中为SSLCaCertificateFile设置添加了ca.crt。在Chrome和Android上仍然可以正常工作,但在iOS中却有完全相同的错误。

谢谢!

Sco*_*tyB 5

归功于这个答案。我注意到,“ s_client” openssl命令的结果确实显示了自签名证书和CA证书,但是只有自签名证书才包含公用名(CN)。我只是简单地更改了第一步,将CN包含在-subj参数中。目前尚不确定证书和CA证书是否确实必要,但是以下步骤无疑可以创建可在Chrome,Android和iOS上运行的自签名证书:

openssl req -new -newkey rsa:2048 -days 820 -nodes -x509 -subj "/C=US/ST=Oklahoma/L=Stillwater/O=My Company/OU=Engineering/CN=test.com" -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 820 -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
Run Code Online (Sandbox Code Playgroud)

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     = serverAuth
subjectAltName       = @alt_names

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

[alt_names]
DNS.1 = test.com
Run Code Online (Sandbox Code Playgroud)

创建证书后:

  1. 将test.crt(至少在我看来不是ca.crt)安装到服务器并重新启动它。
  2. 将test.crt添加到Mac的KeyChain Access(或PC等效)并将其设置为“ Always Trust”,以便它在Chrome和Safari中均可使用。
  3. 通过电子邮件将test.crt发送到您的Gmail帐户,然后在Android模拟器中登录Gmail并点击安装。(它将显示在“设置” /“加密和凭据” /“可信凭据”下的“用户”标签中。)
  4. 将test.crt和ca.crt都拖到您的iOS模拟器上,点击安装,然后在“设置” /“关于” /“证书信任设置”下启用(是!)。

  • 有没有办法说“信任这个根CA及其所有子CA”,而不是手动添加每个域证书?我设法在 macOS 上将 ca.crt 添加到钥匙串并将其标记为受信任,但这似乎不适用于 Android:即使在成功添加它之后(域.crt 确实如此)。 (2认同)