在 Web 浏览器中,JavaScript 是否可以获取有关用于当前页面的 HTTPS 证书的信息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2402121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Within a web browser, is it possible for JavaScript to obtain information about the HTTPS Certificate being used for the current page?
提问by sutch
Is there a method for JavaScript running in a browser to determine which CA certificate is being used to authenticate the remote host for the browser's current HTTPS connection, and also obtain properties of that certificate, such as the name of the CA?
是否有一种方法可以让浏览器中运行的 JavaScript 确定使用哪个 CA 证书来验证浏览器当前 HTTPS 连接的远程主机,并获取该证书的属性,例如 CA 的名称?
If not, are there any other options for programatically obtaining this information, such as ActiveX, Java, CGI on the server side, ...?
如果没有,是否还有其他选项可以以编程方式获取此信息,例如服务器端的 ActiveX、Java、CGI,...?
采纳答案by dlongley
You can use the opensource Forge projectto do this. It implements SSL/TLS in JavaScript. You can make an ajax call to the server and use a callback to inspect the certificate. Keep in mind that the server is the one sending the JavaScript so this shouldn't be used to determine whether or not you trust the server the JavaScript is from. The Forge project does allow cross-domain requests, so if you are using this for trust, you can load the Forge JavaScript from a server you already trust and then contact the server you don't yet trust. However, unless that other server provides a cross-domain policy, you will not be able to perform the cross-domain request.
您可以使用开源Forge 项目来执行此操作。它在 JavaScript 中实现 SSL/TLS。您可以对服务器进行 ajax 调用并使用回调来检查证书。请记住,服务器是发送 JavaScript 的服务器,因此不应使用它来确定您是否信任 JavaScript 来自的服务器。Forge 项目确实允许跨域请求,因此如果您将其用于信任,您可以从您已经信任的服务器加载 Forge JavaScript,然后联系您尚不信任的服务器。但是,除非其他服务器提供跨域策略,否则您将无法执行跨域请求。
https://github.com/digitalbazaar/forge/blob/master/README.md
https://github.com/digitalbazaar/forge/blob/master/README.md
The blog links in the README provide more information on how Forge can be used and how it works.
自述文件中的博客链接提供了有关如何使用 Forge 及其工作原理的更多信息。
回答by mikemaccana
Copying my own answer from Is there any way to access certificate information from a Chrome Extension
从有没有办法从 Chrome 扩展程序访问证书信息中复制我自己的答案
2018 answer: yes, in Firefox 62
2018 年回答:是的,在 Firefox 62 中
You'll need to make a WebExtension, which is also called a browser extension.
您需要制作一个 WebExtension,也称为浏览器扩展。
See accessing security information on MDN
You can also check out the docs for:
您还可以查看以下文档:
You'll need Firefox 62.
您将需要 Firefox 62。
Here's a working background.js
这是一个工作 background.js
var log = console.log.bind(console)
log(`\n\nTLS browser extension loaded`)
// https://developer.chrome.com/extensions/match_patterns
var ALL_SITES = { urls: ['<all_urls>'] }
// Mozilla doesn't use tlsInfo in extraInfoSpec
var extraInfoSpec = ['blocking'];
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onHeadersReceived
browser.webRequest.onHeadersReceived.addListener(async function(details){
log(`\n\nGot a request for ${details.url} with ID ${details.requestId}`)
// Yeah this is a String, even though the content is a Number
var requestId = details.requestId
var securityInfo = await browser.webRequest.getSecurityInfo(requestId, {
certificateChain: true,
rawDER: false
});
log(`securityInfo: ${JSON.stringify(securityInfo, null, 2)}`)
}, ALL_SITES, extraInfoSpec)
log('Added listener')
manifest.json:
manifest.json:
{
"manifest_version": 2,
"name": "Test extension",
"version": "1.0",
"description": "Test extension.",
"icons": {
"48": "icons/border-48.png"
},
"background": {
"scripts": ["background.js"]
},
"permissions": [
"webRequest",
"webRequestBlocking",
"<all_urls>"
]
}
It also may be implemented in Chromium once this code is merged.
一旦合并此代码,它也可以在 Chromium 中实现。
回答by Matthew Flaschen
No. You could obviously do it with AJAX/ActiveX/Java/Flash/Silverlight and a custom server-side script, but I can't see why you would need this.
不。您显然可以使用 AJAX/ActiveX/Java/Flash/Silverlight 和自定义服务器端脚本来实现,但我不明白您为什么需要它。
EDIT: The idea above is that you would make a network request (using one of the above technologies) to the server and ask what certificate was used for that network request. The server could then inspect its own configuration and answer the question.
编辑:上面的想法是您将向服务器发出网络请求(使用上述技术之一)并询问该网络请求使用了什么证书。然后服务器可以检查自己的配置并回答问题。
If the browser is somehow trusting an invalid certificate and connecting to the wrong server (e.g. a MITM server), the server could lie. Once the browser's trust mechanism is compromised, I don't know how to avoid that.
如果浏览器以某种方式信任无效证书并连接到错误的服务器(例如 MITM 服务器),则该服务器可能会撒谎。一旦浏览器的信任机制遭到破坏,我不知道如何避免。
As far as I know, there is no way (purely using client side APIs) to directly ask the browser what cert it's using "for the browser's current SSL connection". Even Forge doesn't do that. It creates an entirely parallelSSL session, but it doesn't let you ask about the browser's native SSL session.
据我所知,没有办法(纯粹使用客户端 API)直接询问浏览器“用于浏览器当前 SSL 连接”的证书。即使 Forge 也不会这样做。它创建了一个完全并行的SSL 会话,但它不允许您询问浏览器的本机 SSL 会话。
回答by sutch
JavaScript running in the web browser does not have access to the certificate information. The certificate information is also not passed through HTTP to the application. My research indicates that there is no way for the web application to determine if a man-in-the-middle attack has injected a bogus certificate somewhere between the host and client.
在 Web 浏览器中运行的 JavaScript 无法访问证书信息。证书信息也不会通过 HTTP 传递给应用程序。我的研究表明,Web 应用程序无法确定中间人攻击是否在主机和客户端之间的某处注入了伪造的证书。
回答by initall
AFAIK not with Javascript alone. But some webservers allow you to access the connection parameters of the thread or process. A serverside script can then send those values along with the request and you use it.
AFAIK 不是单独使用 Javascript。但是有些网络服务器允许您访问线程或进程的连接参数。然后,服务器端脚本可以将这些值与请求一起发送,您可以使用它。
I found this for nginx webserver: http://wiki.nginx.org/NginxHttpSslModule(Look at the bottom of the page for the variables). It should be possible to set them as environment variables and pass them to your FastCGI processes or whatever you use.
我为 nginx 网络服务器找到了这个:http: //wiki.nginx.org/NginxHttpSslModule(查看页面底部的变量)。应该可以将它们设置为环境变量并将它们传递给您的 FastCGI 进程或任何您使用的进程。
AOLServer/Naviserver allows similar access with the nsssl module.
AOLServer/Naviserver 允许使用 nsssl 模块进行类似的访问。
回答by cnst
In practical terms, this has little use -- why would you need to know certificate information from JavaScript on the individual pagealready rendered?
实际上,这没什么用——为什么您需要从已经呈现的单个页面上的 JavaScript 了解证书信息?
If it's not trusted, then obviously your code could have been altered, too, so, it cannot be trusted, either.
If the certificate is actually trusted, then how would you be able to distinguish the scenario from the one where the certificate is not trusted, but your code has been modified through a MitM attack to think otherwise?
如果它不受信任,那么显然您的代码也可能被更改,因此,它也不能被信任。
如果证书实际上是可信的,那么您将如何区分该证书不受信任的情况,但您的代码已通过中间人攻击修改为其他情况?
So, checking certificates would only be useful from within Browser Extensions(which are presumed to be trusted code) as opposed to the scripts in the individual pagesthemselves. Such interface that extensions use is browser-specific, and not all browsers even provide it. For example, whereas Mozilla browsers do let you peek into the certificates (affording extensions like the EFF SSL Observatory), Chromium is still lacking.
因此,与单个页面本身中的脚本相比,检查证书仅在浏览器扩展(假定为受信任的代码)中才有用。扩展使用的这种界面是特定于浏览器的,并不是所有浏览器都提供它。例如,虽然 Mozilla 浏览器确实可以让您查看证书(提供EFF SSL Observatory等扩展),但Chromium 仍然缺乏.


