如何管理自主HTTPS的SSL密钥

时间:2016-01-14 14:02:57

标签: ssl https ssl-certificate self-hosting

我有Windows服务,在最终用户的计算机上侦听https请求,在这种情况下是否有可接受的创建或分发私钥的方法?我是否应该打包专门为localhost请求(例如local.mydomain.com)创建的真实密钥,或者在安装时生成自签名密钥并添加受信任的根CA?

如果重要,该服务使用Nancy Self Host处理请求,并在SYSTEM用户上运行。我们有一个运行在https上的Web应用程序,它将向服务发出CORS请求,用户将在标准Web浏览器上使用它(> = IE10)。只有安装了服务的机器才会向它发出请求。

感谢。

2 个答案:

答案 0 :(得分:2)

我有2个选项,以正确的方式进行,而不是完全不做。

正确的方式

(警告:费用很高)

我们假设您的应用程序托管在云端kosunen.fi下。主要部分由https://www.kosunen.fi处的云提供。

为此域名购买DNS委派。将localhost-a7b3ff.kosunen.fi解析为127.0.0.1 / ::1或实际客户的本地IP地址10.0.0.63 / fe80::xxxx

根据需要为每个localhost-a7b3ff.kosunen.fi购买subCA或获得大规模证书购买协议,颁发证书(更早)或获得颁发的证书(后者)。这些证书将来自受信任的全局CA,因此受到所有浏览器的信任。每个证书仅由一台PC使用。

*.kosunen.fi设置CORS / XSRF / etc位。

完成。

没有这样做

实现localhost流量,实际上非常安全。浏览器通常会拒绝http://localhosthttp://127.0.0.1个网址(以防止从互联网上加载探测本地服务器的JS)。

您仍然需要至少一个解析为localhost.kosunen.fi的DNS条目127.0.0.1 / ::1,即使主机名解析为http://localhost.kosunen.fi,浏览器也会很乐意接受127.0.0.1

有什么风险?

有人在客户端计算机上运行wireshark - 如果有人拥有权限,您的模型无论如何都会完成。

某人劫持或毒害DNS - 将其设置为www.kosunen.fi解析以纠正IP,但localhost.kosunen.fi解析为他们的互联网IP。他们窃取用户浏览器的请求,并且可以包含JS。

缓解ad hoc - 仅提供来自localhost的数据,而不是脚本。设置限制性CORS / XSRF / CSRF。

对于HTTP x HTTPS,您仍然留在CORS中,有解决方法。

超简单的CORS

此处介于两个端口40405050之间,它们与不同主机(localhost与your.com)或协议(HTTPS与HTTP)之间的区别。这是云服务器:

import bottle


@bottle.route("/")
def foo():
    return """
<html><head></head>
<body><p id="42">Foobar</p>
<script>
fetch("http://localhost:5050/").then(
    function(response) {
        console.log("status " + response.status);
        response.json().then(
            function(data) {
                console.log(data);
            }
        );
    }
);
</script>
</body></html>""".strip()

bottle.run(host="localhost", port=4040, debug=True)

这是localhost服务器:

import bottle


@bottle.route("/")
def foo():
    bottle.response.headers["Access-Control-Allow-Origin"] = "*"  # usafe!
    bottle.response.headers["Access-Control-Allow-Methods"] = "HEAD, GET, POST, PUT, OPTIONS"
    bottle.response.headers["Access-Control-Allow-Headers"] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token"
    return """{"foo": 42}"""

bottle.run(host="localhost", port=5050, debug=True)

使其安全(r):在localhost服务器中,读取请求Origin,验证它,例如starswith("https://your.com/")然后返回与请求Allow-Origin相同的Origin。 IMO确保兼容的浏览器仅为your.com上下文中加载的JS提供本地主机内容。当然,破坏的浏览器,或者在同一台机器上运行的任何程序都可以欺骗您的服务器。

答案 1 :(得分:0)

解决此问题的最佳方法是在本地主机名上创建自签名证书,并在IE中添加例外。

有一些服务通过SSL提供“本地主机”,但这些服务都需要使用该服务的所有用户共享私钥,从安全角度来看,有效地使密钥无法使用。只要您只允许本地网络接口上的连接,您可能不会太在意这一点,但是CA会尝试撤销这些证书,因为它们会破坏SSL的完整性(例如,参见http://readme.localtest.me/)。

应该可以在IE11上创建混合内容(HTTPS到HTTP)CORS请求(请参阅https://social.technet.microsoft.com/Forums/ie/en-US/ffec5b73-c003-4ac3-a0fd-d286d9aee89a/https-to-http-cors-issue-in-ie10?forum=ieitprocurrentver)。您只需确保两个站点都在受信任区域中并允许混合内容。我不确定Web应用程序是否可以/应该被信任来运行混合内容,因此自签名证书更明确,并提供更高级别的信任!

您可能无法使用由受信任CA签名的真实证书,因为CA无法根据解析为127.0.0.1的主机名验证您的身份。除非您在域名(即*.mydomain.com)上创建一个通配符证书,该域名也有一个子域local.mydomain.com解析到您的本地计算机,但这可能会干扰{{1}上已有的现有SSL基础结构}。

如果您已在主机名上拥有证书,则可以在客户端的mydomain.com文件中将该主机名设置为127.0.0.1以解决此问题,但这又是更多麻烦而不仅仅是制作自签名证书并信任它。

顺便说一句:不要依赖hosts自签名密钥的安全性,如下所述:https://github.com/letsencrypt/boulder/issues/137。这背后的原因是一些DNS解析器向网络发送localhost个请求。然后可以使用配置错误或受损的路由器拦截流量。