没有互联网连接的WiFi连接设备的最佳做法

时间:2018-04-01 23:52:07

标签: ssl web-applications self-signed

我工作的公司生产的设备通过WiFi提供基于Web的设置和操作界面。该设备通常在不知名的地方使用,因此不能假设存在现有的WiFi网络:因此设备的WiFi模块作为接入点操作,并通过HTTP提供花哨的HTML5 web应用。 (我在2013年选择的WiFi模块唯一可用的选项,最初实现时)。

一开始这个很好,但随着网络的发展它逐渐崩溃。特别是两个问题:

  • 网络应用程序的一部分涉及映射,当然,能够显示一个"你在这里"是非常有用的。地图上的标记 - 但Chrome已拒绝通过HTTP支持HTML5 Geolocation API(甚至没有明确信任该页面的选项),看起来所有其他浏览器也会效仿。

  • 网络应用程序相当大(而且WiFi模块速度很慢),所以我使用HTML5应用程序缓存功能在初次使用应用程序后有效地实现了即时页面加载。不幸的是,主流浏览器已经拒绝通过HTTP允许此功能,无论如何该功能都已被弃用,并且它的后继者(服务工作者)明确地只支持HTTPS。

我不得不重做此功能的硬件和软件,因为原来的WiFi模块已不再可用。目前可用的模块具有更多的CPU功率和存储(并且成本只有十分之一),所以现在可以做很多事情,例如通过HTTPS提供Web应用程序。我通常会看到这样的设备的建议是获得正确的SSL证书,但我不知道在我的情况下这可能如何工作:

  • 当设备实际使用时,通常不会有互联网连接,因此无法验证证书。

  • 可以通过IP地址192.168.1.1或LLMNR / mDNS名称ui.local访问设备。任何类型的地址都不提供SSL证书。

  • 我需要这个永远 - 没有适当的机制来更新设备中的证书。即使是10年(许多自签名证书生成器提供的最长有效期)也不够;我拒绝在设备中建立计划的过时。

或许可以通过向设备添加DNS服务器来进行某种工作,基本上将其作为强制门户,以便可以通过我可以实际购买SSL证书的普通URL来访问它。但是,我发现很多潜在的问题:

  • 如果用户的计算设备设置了静态DNS服务器地址(8.8.8.8或其他),而不是接受来自DHCP的计算设备,则会失败。

  • 如果用户实际上与设备的WiFi连接同时具有互联网连接,则会失败。

  • 如果DNSSEC有效,永久会失败。

  • 还有证书过期的问题。

尽管提出了相反的建议,但似乎只留下了自签名证书作为唯一可行的选择。对他们的一个常见反对意见是"你教导用户忽略有效的安全警告&#34 ;;我明白了你的观点,但我应该做些什么呢?

是否有一些我忽视的方法,这会让我的设备继续使用现代浏览器以及2013年的设备?

2 个答案:

答案 0 :(得分:2)

我同意你的看法,通过HTTPS访问没有公共地址的局域网设备是一个棘手的问题。

恕我直言,应该有一个特殊的TLS版本来解决这些设备,但目前还没有这样的标准。

从我的观点来看,只有自签名证书似乎是可行的。然而,当你谈论“自签名证书生成器”时,它会让我感到寒意,因为你应该永远不会为设备配备预先生成的自签名证书! 从安全角度来看,这是您可以做的最糟糕的事情之一,因为预先生成的证书和密钥对总是可以从固件中提取出来,然后用于攻击您的一个客户(联想和其他计算机制造商刚刚在去年hard way)! 谈到自签名证书,只有一种方法:

  1. 当设备首次启动时,等待处理足够的数据(播种),以便随机生成器可以生成安全的随机数据。

  2. 使用生成的随机数据生成公钥/私钥对

  3. 使用先前生成的密钥对生成自签名证书。使用正确的命令,您可以将有效期结束设置为您想要的任何日期。

  4. 请注意,您可以随时重新执行第3步,例如当用户重新配置IP地址时,您必须在证书中更新它。对于自行开发的客户端(例如在Android或iOS上),您可以执行公钥锁定,这意味着不必(重新)安装证书。

    不幸的是,对于Web浏览器,即使使用相同的公钥,新证书也意味着您必须将证书重新安装为受信任的。

    关于HTML5 Geolocation API:您不能通过HTTPS使用此API吗?如果您在HTTPS页面中使用HTTP资源,混合内容只是一个问题,但另一方面不应该是一个问题。

    BTW:我发现了一些可能对您有用的幻灯片,即使在那种情况下可以进行Internet访问。可能是您从中获得了一些新想法:https://www.w3.org/wiki/images/6/6c/TPAC2016_Local_Discovery_and_HTTPS.pdf

答案 1 :(得分:0)

您可以在自签名证书上指定所需的任何到期日期。这是openssl(-days)的参数。

以下证书在100年后到期:

openssl x509 -in localhost.pem -text -noout

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            c2:a8:fc:a1:29:02:96:dd
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = New York, L = New York, O = localhost, OU = Testing Domain, CN = localhost
        Validity
            Not Before: Apr  7 02:25:51 2018 GMT
            Not After : Mar 14 02:25:51 2118 GMT
        Subject: C = US, ST = New York, L = New York, O = localhost, OU = Testing Domain, CN = localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:96:89:c9:b4:8f:c0:2e:4c:92:15:cd:df:23:b2:
                    f1:6f:34:95:ca:e2:a4:c2:95:3f:1f:b3:50:56:16:
                    65:5a:1a:b9:99:6b:19:67:f0:13:54:76:23:4c:cd:
                    f5:2a:25:6c:d2:e0:67:e9:d5:34:0e:8f:2d:2b:dc:
                    04:3f:bb:e4:07:bd:a4:7a:ee:58:87:6b:cc:b7:1e:
                    79:fc:fc:bd:81:c7:e0:24:1d:91:14:50:70:5b:60:
                    13:ad:c7:eb:fb:67:3b:a9:e5:83:33:fb:ef:f4:26:
                    00:12:e3:af:e9:1e:e9:a2:5b:d1:98:3c:13:c0:30:
                    f0:13:9c:52:a3:b1:e7:3a:73:47:ce:ab:f9:5f:c4:
                    ff:74:1e:0c:86:ec:83:d6:b5:6d:36:31:00:26:97:
                    d8:74:39:cb:75:24:31:39:cc:e4:a1:78:38:92:07:
                    b4:a5:06:5a:8e:8b:0c:fa:7e:5e:55:7e:59:cf:f1:
                    1f:05:2e:e6:c2:6a:cf:4c:03:6a:66:b8:19:64:ae:
                    90:81:d9:28:37:2f:09:c1:b3:98:8a:bf:39:0a:0b:
                    23:db:55:79:02:83:fe:9d:be:ac:b8:3c:e5:1e:76:
                    5c:69:fe:f4:34:78:d4:36:82:0f:6e:c1:19:fe:39:
                    7f:fd:f0:4f:13:b6:2a:26:e6:ce:b0:fd:51:3d:38:
                    61:41
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                D6:DF:EB:FA:73:85:C9:22:AA:6D:79:E5:F9:16:01:2B:CC:E7:D8:D0
            X509v3 Authority Key Identifier: 
                keyid:D6:DF:EB:FA:73:85:C9:22:AA:6D:79:E5:F9:16:01:2B:CC:E7:D8:D0

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         4f:ca:30:3f:fe:61:73:16:3f:a1:6d:5a:35:c1:b6:97:d6:63:
         89:34:6e:05:e6:e6:84:7b:3b:b4:fc:89:65:7a:31:46:97:8f:
         00:11:c7:61:97:86:b8:31:c7:a7:91:f7:c9:19:4e:0a:39:d7:
         5e:95:52:17:92:8a:84:ce:6a:1b:1c:14:f2:15:18:62:78:07:
         1e:d9:3c:5d:9c:28:65:42:bf:4f:61:0f:a3:86:e6:ff:38:34:
         23:97:11:20:3c:5b:82:4a:ea:05:af:6d:5e:83:30:be:6d:64:
         de:85:b8:bb:89:60:59:7a:c8:1f:ba:2d:02:04:34:89:65:32:
         2c:10:f7:db:97:c3:ba:e2:ed:27:8a:bb:8d:9e:92:0a:d3:2e:
         ad:9e:fb:15:fc:25:73:0d:e2:f9:45:3b:18:fd:89:e6:6b:31:
         18:64:46:e2:dc:ad:e0:f3:f8:c1:b2:e6:93:bc:b3:db:9a:bc:
         d3:58:38:68:e2:28:b4:6d:ca:07:d8:af:21:dc:10:bd:c0:75:
         3f:b1:d2:24:96:5d:dd:a3:d2:e2:95:39:67:6b:06:bb:4d:91:
         76:4f:9b:ce:7f:25:39:47:73:3e:fd:81:82:15:ac:6a:2c:cb:
         82:76:04:b1:91:41:cf:8a:68:70:cd:7d:3f:2f:c9:1d:d5:a7:
         3e:d0:3d:00

您可以使用以下脚本生成它:

#! /bin/bash

mkdir /tmp/scert 2>/dev/null
rm -r /tmp/scert/* 2>/dev/null

if [ $# -ne 1 ];
then
    echo "Usage: scert <name>"
    exit
fi

if [ -e "/etc/ssl/private/$1.key" ];
then
    echo "/etc/ssl/private/$1.key already exists"
    exit
fi

if [ -e "/etc/ssl/certs/$1.crt" ];
then
    echo "/etc/ssl/certs/$1.crt already exists"
    exit
fi

if [ -e "/etc/ssl/certs/$1.pem" ];
then
    echo "/etc/ssl/certs/$1.pem already exists"
    exit
fi

echo "[req]" > /tmp/scert/tmp.cnf
echo "default_bits = 2048" >> /tmp/scert/tmp.cnf
echo "prompt = no" >> /tmp/scert/tmp.cnf
echo "default_md = sha256" >> /tmp/scert/tmp.cnf
echo "distinguished_name = dn" >> /tmp/scert/tmp.cnf
echo "" >> /tmp/scert/tmp.cnf
echo "[dn]" >> /tmp/scert/tmp.cnf
echo "C=US" >> /tmp/scert/tmp.cnf
echo "ST=New York" >> /tmp/scert/tmp.cnf
echo "L=Rochester" >> /tmp/scert/tmp.cnf
echo "O=$1" >> /tmp/scert/tmp.cnf
echo "OU=Testing Domain" >> /tmp/scert/tmp.cnf
echo "emailAddress=spam@uce.gov" >> /tmp/scert/tmp.cnf
echo "CN = localhost" >> /tmp/scert/tmp.cnf

echo "authorityKeyIdentifier=keyid,issuer" > /tmp/scert/tmp.ext
echo "basicConstraints=CA:FALSE" >> /tmp/scert/tmp.ext
echo "keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment" >> /tmp/scert/tmp.ext
echo "subjectAltName = @alt_names" >> /tmp/scert/tmp.ext
echo "" >> /tmp/scert/tmp.ext
echo "[alt_names]" >> /tmp/scert/tmp.ext
echo "DNS.1 = localhost" >> /tmp/scert/tmp.ext

openssl genrsa -des3 -passout pass:xxxx -out /tmp/scert/tmp.pass.key 2048
openssl rsa -passin pass:xxxx -in "/tmp/scert/tmp.pass.key" -out "/tmp/scert/tmp.key"

openssl req -x509 -new -nodes -key /tmp/scert/tmp.key  -subj "/C=US/ST=New York/L=New York/O=$1/OU=Testing Domain/CN=localhost" -sha256 -days 36500 -out /tmp/scert/$1.pem

openssl req -new -sha256 -nodes -out /tmp/scert/tmp.csr -newkey rsa:2048 -keyout /tmp/scert/$1.key -config <( cat /tmp/scert/tmp.cnf )

openssl x509 -req -in /tmp/scert/tmp.csr -CA /tmp/scert/$1.pem -CAkey /tmp/scert/tmp.key -CAcreateserial -out /tmp/scert/$1.crt -days 36500 -sha256 -extfile /tmp/scert/tmp.ext

if [ -e "/tmp/scert/$1.key" ];
then
    sudo cp /tmp/scert/$1.key /etc/ssl/private
    sudo chown root:ssl-cert /etc/ssl/private/$1.key
    sudo chmod 640 /etc/ssl/private/$1.key
    ls -al /etc/ssl/private/$1.key
else
    echo "ERROR: /tmp/scert/$1.key not found"
fi

if [ -e "/tmp/scert/$1.crt" ];
then
    sudo cp /tmp/scert/$1.crt /etc/ssl/certs
    sudo chown root:root /etc/ssl/certs/$1.crt
    sudo chmod 755 /etc/ssl/certs/$1.crt
    ls -al /etc/ssl/certs/$1.crt
else
    echo "ERROR: /tmp/scert/$1.crt not found"
fi

if [ -e "/tmp/scert/$1.pem" ];
then
    sudo cp /tmp/scert/$1.pem /etc/ssl/certs
    sudo chown root:root /etc/ssl/certs/$1.pem
    sudo chmod 755 /etc/ssl/certs/$1.pem
    ls -al /etc/ssl/certs/$1.pem
else
    echo "ERROR: /tmp/scert/$1.pem not found"
fi

rm -r /tmp/scert/* 2>/dev/null

echo "DONE"