Javascript非对称加密和认证

发布于 2024-12-04 12:23:19 字数 1678 浏览 1 评论 0原文

这里的一些人正在开发一个应用程序,其中包含一些可通过登录访问的“安全区域”。过去,登录表单和后续的“安全”页面都是通过 http 传输的纯文本,因为它是一个需要访问的应用程序在几乎不可能使用 SSL 的共享服务器上使用(例如 WordPress 等)。大多数人只是耸耸肩,因为这就是他们所期望的——这根本不是一家国家银行。

我们现在正在考虑使用 JavaScript 前端编写下一个版本,其优点是加载所有图像和内容。 CSS 一次,然后使用 extJS(或者可能是 jQuery)将 HTML 写入 DOM。我们希望在发送到服务器之前对客户端的用户输入进行加密,然后在将服务器输出呈现为 HTML 之前在浏览器上解密,以便为用户引入某种安全性。减少页面加载时间也有好处,因为我们只来回发送 gzip 压缩的 JSON。

在尝试过程中,我们意识到我们正在寻找的加密基本内容的方法首先也可以作为登录的身份验证机制。

为简单起见...:

  • 用户通过标准 http 连接到登录页面,浏览器在其中下载包含哈希和加密算法(例如 SHA-256 和 AES)的 JavaScript 包。
  • 用户在登录表单中输入用户名密码秘密
  • 浏览器 JavaScript 通过 AJAX 将用户名密码的哈希值发送到服务器。 秘密仅存储在JavaScript中,并且永远不会通过互联网发送。
  • 服务器查找哈希并从数据库中检索用户名秘密
  • 服务器将用户名秘密的哈希值(与浏览器相同的算法)发送回浏览器。
  • 浏览器 JavaScript 创建用户名秘密 的哈希值,并将其与从服务器发回的哈希值进行比较。
  • 如果它们相同,浏览器 JavaScript 将使用 secret 加密 response 并将消息发送回服务器。
  • 服务器使用secret解密消息以找到预期的响应并启动新会话。
  • 后续通信均使用 secret 进行加密和解密。

这种类型的系统似乎有一些优点,但我们的想法是否正确:

  • 如果服务器设法创建 username的哈希值,则用户知道他们正在与服务器通信Secret,证明服务器知道并理解用户名secret
  • 如果服务器设法使用 secret 加密 response,证明用户知道 secret,则服务器知道用户是真实的。
  • secret 永远不会以纯文本形式传输,也不可能从哈希值中确定 secret
  • 嗅探器只会找出“安全”URL 并检测查询字符串中的压缩散列和加密。如果他们向格式错误的 URL 发送请求,则不会给出任何响应。如果他们以某种方式设法猜测适当的请求,他们仍然必须能够解密它。

这一切看起来足够快,以至于用户无法察觉。任何人都可以看穿这一点,因为我们都认为我们不应该玩 JavaScript 加密!

Some of the guys here are developing an application which incorporates some 'secure areas' accessible by logging in. In the past, the login form and subsequent 'secure' pages were all plain text transmitted over http, as it's an application that goes out for use on shared servers where there is little chance of being able to use SSL (think WordPress and the like). Most people just shrugged their shoulders as that's all they expected - it's hardly a national bank.

We are now thinking of writing the next version using a JavaScript front end, with the advantage of loading all the images & CSS once, then writing HTML into the DOM thereafter with extJS (or maybe jQuery). We'd like to encrypt user input at the client before being sent to the server, then decrypt server output at the browser before being rendered to HTML so as to introduce some sort of security for users. There are also gains to be had with reducing page loading times, as we're only sending gzipped JSON back and forth.

While playing around, we realised that the method we were looking at to encrypt the basic stuff also doubled up as an authentication mechanism for login in the first place.

For simplicity...:

  • The user connects to the login page over standard http, where the browser downloads the JavaScript package containing the hashing and encryption algorithms (SHA-256 and AES for example).
  • User enters username, password and secret into a login form.
  • The browser JavaScript sends a hash of username and password to the server via AJAX. The secret is only stored in JavaScript and is never sent across the internet.
  • The server looks up the hash and retrieves username and secret from the database.
  • The server sends a hash (same algorithm as the browser) of username and secret back to the browser.
  • The browser JavaScript creates a hash of username and secret and compares it to the hash sent back from the server.
  • If they are the same, the browser JavaScript encrypts response with secret and sends the message back to the server.
  • The server decrypts the message with secret to find the expected response and starts a new session.
  • Subsequent communications are encrypted and decrypted both ways with secret.

There seem to be a few advantages of this type of system, but are we right in thinking:

  • The user knows they are talking to their server if the server manages to create a hash of username and secret, proving the server knows and understands username and secret.
  • The server knows the user is genuine if they manage to encrypt response with secret, proving the user knows secret.
  • At no time is secret ever transmitted in plain text, or is it possible to determine secret from the hash.
  • A sniffer will only ever find out the 'secure' URL and detect compressed hashes and encryptions in the query string. If they send a request to to the URL that is malformed, no response is given. If they somehow manage to guess an appropriate request, they still have to be able to decrypt it.

It all seems quick enough as to be imperceptible to the user. Can anyone see through this, as we all just assumed we shouldn't be playing with JavaScript encryption!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的痛♀有谁懂 2024-12-11 12:23:19

不要这样做。请使用 SSL/TLS。请参阅Javascript 加密技术被认为有害

Don't do this. Please use SSL/TLS. See Javascript Cryptography Considered Harmful.

淡忘如思 2024-12-11 12:23:19

如果您可以提供单个 SSL 站点来安全地传送 JavaScript(以避免上述攻击),那么您可以在为其他站点生成自签名证书后,使用开源 Forge 库为其他站点提供跨域 TLS 连接。如果您选择不同的方向,Forge 库还提供其他基本的加密内容。 Forge 有一个几乎全部由 JavaScript 组成的 XMLHttpRequest 包装器,其中一小部分利用 Flash 的套接字 API 来实现跨域通信。

http://digitalbazaar.com/2010/07/20/javascript-tls- 1/

https://github.com/digitalbazaar/forge

If you can provide a single SSL site to deliver your JavaScript securely (to avoid the attack mentioned above), then you can use the opensource Forge library to provide cross-domain TLS connections to your other sites after generating self-signed certificates for them. The Forge library also provides other basic crypto stuff if you opt to go in a different direction. Forge has an XMLHttpRequest wrapper that is nearly all JavaScript, with a small piece that leverages Flash's socket API to enable cross-domain communication.

http://digitalbazaar.com/2010/07/20/javascript-tls-1/

https://github.com/digitalbazaar/forge

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文