如何以编程方式测试网站是否使用 HTTPS?

How can I programmatically test to see if a website uses HTTPS?

我想构建某种类型的脚本来判断网站是否使用 https。

以编程方式确定这一点的方法是什么?我尝试访问我自己知道没有 https 的域之一,但服务器仍然给了我一个 200 代码(至少,根据我使用的 Chrome 扩展)。

是否存在某种我可以捕捉到的错误,或者其他一些在站点之间保持一致的信息?

在 Windows 上,您可以使用 free Basic Edition of HttpWatch and its automation interface 编写一个程序来访问您要测试的站点。

条目 class 上的 Error property 允许您检测 HTTP 连接失败的情况。

理论上,您可以提前知道是否应该使用 HTTPS。通过这个,我的意思是用户有一部分判断期望对某些站点使用 HTTPS。在现实世界中,走进银行和走进咖啡店时,您通常会有不同的安全期望。您通常不愿意向酒吧后面的人提供与您的银行家相同的详细信息。这同样适用于网络。

也就是说,您确实可以测试是否可以与某个网站建立HTTPS连接。问题是无法建立此连接可能意味着以下几点:

  • 该站点根本不支持 HTTPS,
  • 存在临时连接问题,
  • 有攻击者阻止您建立该连接。

许多站点会尝试通过重定向将您从 HTTP 升级到 HTTPS,以使用户知道 HTTPS 可用,并希望让他们在下次访问该站点时期待它。有些站点甚至会使用 HTTP 严格传输安全 (HSTS) 来强制您在下次访问该站点时记住该升级。如果您可以假设您的第一个连接没有受到影响,这是一个合理的折衷方案。

What is a way of programmatically determining this? I tried visiting one of my own domains that I know does not have https, but the server still gave me a 200 code.

如果您的域没有有效证书,证书验证应该会失败,并且您根本无法获得任何 HTTP 状态代码作为响应。

我猜想您使用的脚本没有进行任何证书验证,也许这些域指向共享托管环境,其中具有相同 IP 地址的其他服务启用了 HTTPS。

您至少应该确保您的脚本正确验证了证书:

  • 您应该能够及时验证证书的真实性和由您信任的 CA 颁发的有效性。 (这通常在 RFC 3820 和 RFC 5820 中指定)
  • 您应该能够验证它对于您要查找的主机名是否有效。 (这通常在 RFC 2818 和 RFC 6125 中指定。)

并非所有 SSL/TLS 库都默认启用此功能(尤其是第二点)。

我不确定您的脚本使用了什么或者您提到的扩展名有什么作用。例如,如果您使用的是 curl,请确保您没有使用 -k--insecure,而您使用的是 wget,请确保您没有使用 --no-check-certificate。如果您使用的是 libcurl,则应确保您是 using the VERIFYPEER and VERIFYHOST properly。如果这不是您正在使用的,请在其他实现中寻找类似的选项,并且不要忽略浏览器警告。