我有一个桌面产品,它使用嵌入式网络服务器,该服务器将使用自签名证书。
我可以在网页中放入一些内容来检测他们尚未将根 CA 添加到其受信任列表中,并显示链接或 DIV 或指导他们如何执行此操作的内容吗?
我想也许一个 DIV 包含有关安装 CA 的说明,以及一个运行一些测试的 Javascript(尝试在没有内部警告的情况下访问某些内容??),并在测试成功时隐藏 DIV。 或者类似的东西...
来自杰出的 SO 社区的任何想法吗? :)
I have a desktop product which uses an embedded webserver which will use self-signed certs.
Is there something that I can put in a web page that would detect that they haven't added the root CA to their trusted list, and display a link or DIV or something directing them how to do it?
I'm thinking maybe a DIV that has instructions on install the CA, and a Javascript that runs some test (tries to access something without internal warnings??), and hides the DIV if the test succeeds. Or something like that...
Any ideas from the brilliant SO community ? :)
发布评论
评论(9)
你为什么要这样做? 仅仅因为网站告诉用户安装根 CA 证书就训练用户不加区别地安装根 CA 证书是一个坏主意。 你正在破坏整个信任链。 具有安全意识的用户会忽略您安装证书的建议,并可能得出结论认为您没有认真对待安全性,因为您没有费心从现有 CA 获取证书。
您真的需要 HTTPS 吗? 如果是这样,您可能应该硬着头皮与 CA 达成协议,以便于向您的客户提供正确的 CA 签名服务器证书。 如果 Web 服务器仅用于来自桌面应用程序的本地连接,您应该在安装过程中将自签名证书添加到受信任列表中,或者切换到 HTTP。
Why do you want to do this? It is a bad idea to train users to indiscriminately install root CA certificates just because a web site tells them to. You are undermining the entire chain of trust. A security conscious user would ignore your advice to install the certificate, and might conclude that you are not taking security seriously since you did not bother to acquire a certificate from an existing CA.
Do you really need HTTPS? If so, you should probably bite the bullet and make a deal with a CA to facilitate providing your customers with proper CA signed server certificates. If the web server is only used for local connections from the desktop app, you should either add the self-signed certificate to the trusted list as part of the installation process, or switch to HTTP instead.
假设您了解 C# 并且想要安装 pfx 文件。创建一个将从 url 运行的 exe。关注此 URL
Assuming you know C# and you want to install a pfx file.Create a exe that will be run from a url.Follow this URL
我唯一的想法是使用框架和一些 javascript。
框架的第一个元素将充当看门狗,等待 x 时间 (javascript setTimeout),然后向用户显示自定义 ssl 失败消息,其中包含下载自签名证书的超链接或说明。
第二个框架元素尝试 https 连接,如果成功,则重置看门狗框架,使其永远不会触发。 如果失败(假设 https 证书验证失败),看门狗消息将触发并呈现给用户。
根据您的浏览器,您很可能仍然会看到一些安全警告,但您至少能够推送自己的内容,而不需要用户在没有适当信任链的情况下运行不受信任的代码(这会比安全性更糟糕) POV(而不是接受证书验证错误并建立不受信任的 ssl 会话)
可以使用其他测试方法(例如 XMLHttpRequest 等)对该概念进行改进。
The only idea I have is to use frames and some javascript.
The first element of the frame will act as a watchdog waiting x amount of time (javascript setTimeout) before showing your custom ssl failure message to the user with hyperlinks or instructions to download the self-signed cert.
The second frame element attempts the https connection and if successful resets the watchdog frame so that it never fires. If it fails (assume https cert validation failed) the watchdog message would then fire and be presented to the user.
Depending on your browser you will most likely still see some security warning with the approach but you would at least be able to push your own content without requiring users to run untrusted code with no proper trust chain (This would be much much worse from a security POV than accepting the cert validation errors and establishing an untrusted ssl session)
Improvements to the concept may be possible using other testing methods such as XMLHttpRequest et al.
你不应该这样做。 根证书不是您只需安装的东西,因为添加根证书可能会损害 https 为您提供的任何安全性。
但是,如果您正在制作桌面应用程序,则只需侦听 127.0.0.1。 这样,流量就永远不会离开用户计算机,攻击者也无法监听。
You should not do this. Root certificates are not something you just install, since adding one could compromise any security given to you by https.
However if you are making a desktop app then just only listen to 127.0.0.1. That way the traffic never leaves the users computer and no attacker can listen in.
您可能会尝试在每个用户会话中添加一些(隐藏的)Flex 元素或 Java Applet。
它只会下载服务器的任何 https 页面,并获取有关连接的所有信息:
我想 Flex(对用户来说更常见)应该有类似的方法从用户的角度验证 https 证书。 它还应该共享操作系统的可信证书。 存储,而 Java 可能有自己的存储。
You might try to add some (hidden) Flex element or Java Applet once per user session.
It will just download any https page of your server and will get all information about connection:
I suppose Flex (which is more common to users) shoul have similar ways of validating https certificate from user's point of view. It should also share OS' trusted cert. store while Java might have its own.
由于服务器在客户端计算机(桌面产品)上运行,它是否可以不使用 winapi/os 函数检查支持的浏览器是否安装了证书? 我知道 Firefox 在用户的配置文件目录中有一个证书数据库,而 IE 可能将信息保存在注册表中。 它对于所有浏览器来说并不可靠,但如果服务器只是在“找到证书”和“请确保您在继续之前安装了证书”之间进行选择,那么不会造成任何损害,因为用户可以选择任一方式继续。
您还可以通过提供嵌入式浏览器(即 gecko)来简化问题,这样您就只有 1 个浏览器来处理,这简化了很多事情(包括预安装根 CA)。
Since the server is running on the client machine (desktop product) can it not check the supported browsers for installed certs using winapi/os functions? I know Firefox has a cert database in the user's profile directory and IE probably keeps information in the registry. It wouldn't be reliable for all browsers but if the server simply chooses between "Certificate Found" and "Please ensure you have installed the cert before continuing" then no harm is done as the user can choose to continue either way.
You could also simplify matters by providing an embedded browser as well (ie, gecko), this way you only have 1 browser to deal with which simplifies a lot of things (including pre-installing the root CA).
回顾一下:您正在桌面应用程序上设置网络服务器; 每个桌面都有自己的网络服务器,但您希望使用 SSL 来保护与该网络服务器的连接。
我猜想证书存在几个问题,其中之一是用于访问桌面的主机名必须与证书匹配。 在这种情况下,您别无选择,只能在客户端上生成证书。 您需要允许用户通过某种方式指定主机名,以防无法从主机本身检测到外部人员使用的名称。
对于那些不想依赖自签名证书的人,我还建议允许管理员安装受信任的证书。 通过这种方式,您还可以将可信证书维护的成本分摊给真正需要的管理员。
最后,根据我的经验,浏览器要么允许或拒绝自签名证书,并且服务器无法知道证书是否被拒绝、暂时接受或永久接受。 我认为一定有某种机制来处理 SSL 故障,但典型的 Web 编程不在该层运行。 无论如何,如果 SSL 失败,网络服务器唯一能做的就是回退到非 SSL,并且您已在评论中指出不能使用任何非 SSL 的内容。 我认为你应该尝试取消该限制; 在这种情况下,非 SSL 起始页将非常有用:它可以测试(使用框架或图像或 JSON 或 AJAX)https 连接,并且可以链接到有关如何设置证书或在哪里下载证书的文档。证书的安装程序。
如果浏览器由于自签名证书而无法连接,并且您根本不允许使用纯 HTTP,那么您还可以通过什么其他方式与用户通信? 没有其他渠道,你也无法建立一个渠道,因为你没有任何沟通。
您在评论中提到编写一个用于安装证书的 win32 应用程序。 您可以在安装应用程序本身时安装证书,但这对任何远程浏览器没有帮助,并且本地浏览器不需要 SSL 来访问本地主机。
To recap: you are setting up webservers on desktop apps; each desktop will have its own webserver, but you want to use SSL to secure the connection to that webserver.
I guess there are several problems here with certificates, one being that the hostname used to access the desktop has to match the certificate. In this case you have little choice but to generate certificates on the client. You'll need to allow the user some way to specify the host name in case the name used by outsiders can't be detected from the host itself.
I'd also suggest allowing for an admin to install a trusted cert, for those who don't want to rely on self-signed certs. This way you can also offload the cost of trusted cert maintenance to the admins who really want it.
Finally, in my experience browsers either allow or refuse the self-signed cert and there is no way for the server to know if the cert is denied, or temporarily accepted, or permanently accepted. I assume there must be a mechanism somewhere to handle SSL failures but typical web programming doesn't operate at that layer. In any case, the only thing a webserver can do if SSL fails is to fallback to non-SSL, and you've indicated in a comment that you can't have anything non-SSL. I think you should try to have that restriction lifted; a non-SSL start page would be extremely helpful in this situation: it can test (using frames or images or JSON or AJAX) the https connection, and it can link to documentation about how to set up the certificate, or where to download an installer for the cert.
If the browser won't connect because of a self-signed cert, and you're not allowed to use plain HTTP at all, by what other means could you communicate with the user? There are no other channels and you can't establish one because you don't have any communication.
You mentioned in a comment writing a win32 app for installing the cert. You could install a cert at the time you install the application itself, but that doesn't help any remote browsers, and a local browser doesn't need SSL to access localhost.
我们一直致力于一个名为 Forge 的开源 JavaScript 项目,该项目与这个问题相关。 您有用户可以访问的网站吗? 如果是这样,那么您可以使用用于跨域的 Flash + 用于 TLS 的 JavaScript 组合,通过您的网站提供与这些桌面应用程序的安全连接。 它将要求您在网站上实现一些 Web 服务来处理桌面应用程序证书的签名证书(或者让您的桌面应用程序上传自签名证书,以便可以通过 JavaScript 访问它们)。 我们在这里描述它的工作原理:
http://blog.digitalbazaar。 com/2010/07/20/javascript-tls-1/
设置网站的另一种方法是直接在桌面应用服务器上托管 JavaScript+Flash,但安全性较低,因为它允许中间人攻击。 您可以让用户通过常规 http 访问您的桌面应用程序来下载 JS+Flash+SSL 证书,然后通过 JS 开始使用 TLS。 如果您使用本地主机连接,MiTM 攻击可能不会那么令人担忧——也许足以让您考虑此选项。
We've been working on an opensource JavaScript project, called Forge, that's related to this problem. Do you have a website that your users could access? If so, then you could provide a secure connection to those desktop apps via your website using a combination of Flash for cross-domain + JavaScript for TLS. It will require you to implement some web services on your website to handle signing certificates the desktop app certificates (or having your desktop apps upload the self-signed certs so they can be accessed via JavaScript). We describe how it works here:
http://blog.digitalbazaar.com/2010/07/20/javascript-tls-1/
An alternative to setting up a website, but is less secure because it allows for a MiTM attack is to host the JavaScript+Flash directly on the desktop app server. You could have your users hit your desktop app over regular http to download the JS+Flash+SSL cert, but then start using TLS afterwards via the JS. If you're on a localhost connection the MiTM attack might be a little less worrisome -- perhaps enough for you to consider this option.
ActiveX 控件可以解决这个问题。 但我真的没有插话来帮助解决方案,更多的是不同意你所做的事情存在安全风险的立场。
需要明确的是,您需要一个安全密码(希望是 AES 而不是 DES),并且已经控制了您的端点,只是无法完全排除可能捕获明文密码或其他敏感数据的混杂模式网络嗅探器。
SSL 是“安全套接字层”,根据定义,不依赖于任何证书。
然而,所有有效的现代密码都需要它来验证隧道端点,这并不总是每个应用程序所必需的; 我在使用 Web 服务 API 管理节点的众多后端数据中心自动化例程中遇到过一个挫折,其中“用户”实际上是在 RESTful 命令协商之前需要加密密钥交换的进程。
就我而言,VLAN 通过 ACL 进行保护,因此我确实“可以”发送明文身份验证标头。 但光是打字就让我在嘴里吐了一点。
我确信我会因为写下这些内容而受到批评,但我是身经百战的人,在我 IT 职业生涯的第 10 到 15 年里,我也会对你做出同样的评论。 因此,我对他们的担忧表示同情,并且非常感谢他们对安全的热情足以激怒我。 他们最终会解决这个问题......
但我确实同意这样一个事实:“训练”用户自行安装根 CA 是一个坏主意。 另一方面,如果您使用自签名证书,则必须培训他们安装该证书。 如果用户不知道如何确定 CA 证书是否可信,他们肯定无法从 CA 证书确定自签名证书,因此这两个过程都会产生相同的效果。
如果是我,我会自动化该流程,而不是让它帮助最终用户,以便尽可能对他们隐藏,就像适当的 PKI 对企业所做的那样。
说到这里,我只是想到了一个可能的解决方案。 使用 Microsoft PKI 模型。 使用 Server 2012 R2,您可以通过“工作区”使用“设备控制”将可信密钥传递到甚至不是域成员的端点,并且客户端计算机可以订阅多个工作区,因此如果它们订阅,它们不会仅提交给您的工作区。 一旦完成并进行身份验证,AD 证书服务角色将推送所有必需的根 CA 证书,如 Active Directory 或指定的 LDAP 服务器中存在的证书。 (如果您使用离线 CA 服务器)
另外,我意识到这个线程已经有 7 年历史了,但我确信它仍然被很多需要类似解决方案的人引用,并且觉得有义务分享相反的意见。 (好吧,微软,我给你的插件的回扣在哪里?)
-cashman
An ActiveX control could do the trick. But I really didn't chime in to help with the solution, more to disagree with the stance that what you are doing is a security risk.
To be clear, you are needing a secure cipher (hopefully AES and not DES), and are already in control of your endpoints, just not able to completely rule out promiscuous-mode network sniffers that could catch clear-text passwords or other sensitive data.
SSL is a "Secure Socket Layer", and by definition, is NOT dependent upon ANY certificates.
However, all effective modern ciphers require it to authenticate the tunnel endpoints, which is not always a necessity for every application; a frustration I have dealt with in numerous back-end datacenter automation routines using web service APIs to manage nodes, where the "users" were actually processes that needed encrypted key exchange prior to a RESTful command negotiation.
In my case, the VLANs were secured via ACLs, so I really "could" send clear-text authentication headers. But just typing that made me throw up in my mouth a little bit.
I'm sure I'll get flamed for typing this, but I'm extremely battle-hardened and would've made the same comments to you in years 10-15 of my IT career. So I empathize with their worries, and very much appreciate if they are passionate enough about security to flame me. They'll figure it out eventually.....
But I do agree with the fact that it is a BAD idea to "train" users to install root CA's on their own. On the other hand, if you use a self-signed cert, you have to train them to install that. And if a user doesn't know how to determine if a CA Cert is trustworthy, they definitely won't be able to determine a self-signed cert from a CA Cert, and thus either process would have the same effect.
If it were me, I would automate the process instead of having it assist the end-users, so that it becomes as hidden from them as possible, just like a proper PKI would do for an enterprise.
Speaking of which, I just thought of a potential solution. Use the Microsoft PKI Model. With Server 2012 R2, you can deliver trusted keys to endpoints that are not even domain members using "device control" via "workspaces", and the client machines can subscribe to multiple workspaces, so they are not committed solely to yours if they subscribe. Once they do, and authenticate, the AD Certificate Services Role will push all root CA Certs necessary, as are present in active directory, or specified LDAP server. (In case you are using offline CA servers)
Also, I realize this thread is like 7 years old, but am sure it still gets referenced by a good number of people needing similar solutions, and felt obligated to share a contrasting opinion. (Ok Microsoft, where's my kickback for the plug I gave you?)
-cashman