SSL 认证适用于本地主机,但不适用于计算机名称或 IP

2024-03-21

我们有一个在服务器上运行的 Web 应用程序,它通过 XDomainRequest 发布 http 请求(因为 IE9)。

有很多客户端计算机都有一个控制台应用程序通过套接字侦听器侦听端口。客户打开 Web 应用程序 IE9 浏览器,当他们单击链接时,网页会发送如下请求:

"https://localhost:端口号/应用程序名称/doSomething https://localhost:portNumber/applicationName/doSomething" "https://计算机名称:端口号/应用程序名称/doSomething https://computerName:portNumber/applicationName/doSomething" "https://ip地址:端口号/应用程序名称/doSomething https://ipAddress:portNumber/applicationName/doSomething"

第二个和第三个请求是为了控制台其他用户计算机的应用程序而发出的。

问题是,如果请求来自本地主机,控制台应用程序在读取传入数据和发送回响应方面不会出现问题。但 如果请求带有计算机名称或 IP 地址,则浏览器会显示认证警告并希望用户单击 “继续访问此网站(不推荐)”链接。

我们考虑通过代码创建三个不同的证书。 但即使使用 sslstream 与其中三个是可能的,我们也不能决定选择真正的认证,因为我们首先进行身份验证,然后接收数据。因此,当我们捕获传入请求时,身份验证必须已经完成。

另一种方法是强制套接字侦听器或 sslstream 将所有这三个请求视为本地主机。因此,对于每一个身份验证都将作为本地主机进行。但我找不到实际的方法。

这是代码。我给出代码是因为 SslStream 的用法可能有一些错误。

using System;
using System.Net.Sockets;
using System.Net;
using System.Configuration;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;
using System.IO;
using System.Net.Security;
using System.Security.Authentication;
using System.Threading;
using System.Text;

namespace StackOverFlowProject
{
    class StackOverFlowSample
    {
        private static ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
        private static X509Certificate _cert = null;

        static void Main(string[] args)
        {
            StackOverFlowSample stackOverFlowSample = new StackOverFlowSample();
            stackOverFlowSample.StartListening();
        }

        private void StartListening()
        {
            GetCertificate();

            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);

            if (localEndPoint != null)
            {
                Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                if (listener != null)
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(10);

                    Console.WriteLine("Socket listener is running. Waiting for requests...");

                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                }
            }
        }

        private static void GetCertificate()
        {
            byte[] pfxData = File.ReadAllBytes(Application.StartupPath + @"\" + "localhost.pfx");

            _cert = new X509Certificate2(pfxData, "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
        }


        private void AcceptCallback(IAsyncResult result)
        {
            Socket listener = null;
            Socket handler = null;
            StateObject state = null;
            SslStream sslStream = null;

            _manualResetEvent.Set();

            listener = (Socket)result.AsyncState;

            handler = listener.EndAccept(result);

            state = new StateObject();

            if (handler.RemoteEndPoint != null)
            {
                state.clientIP = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
            }

            sslStream = new SslStream(new NetworkStream(handler, true));
            sslStream.AuthenticateAsServer(_cert, false, SslProtocols.Tls, true);

            sslStream.ReadTimeout = 100000;
            sslStream.WriteTimeout = 100000;

            state.workStream = sslStream;

            if (state.workStream.IsAuthenticated)
            {
                state.workStream.BeginRead(state.buffer, 0, StateObject.BufferSize, ReceiveCallback, state);
            }

            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
        }

        private void ReceiveCallback(IAsyncResult result)
        {
            StateObject stateObject = null;
            SslStream sslStreamReader = null;

            byte[] byteData = null;

            stateObject = (StateObject)result.AsyncState;
            sslStreamReader = stateObject.workStream;

            int byteCount = sslStreamReader.EndRead(result);

            Decoder decoder = Encoding.UTF8.GetDecoder();
            char[] chars = new char[decoder.GetCharCount(stateObject.buffer, 0, byteCount)];
            decoder.GetChars(stateObject.buffer, 0, byteCount, chars, 0);
            stateObject.sb.Append(chars);

            if (byteCount > 0)
            {
                stateObject.totalReceivedBytes += byteCount;

                string[] lines = stateObject.sb.ToString().Split('\n');

                if (lines[lines.Length - 1] != "<EOF>")
                {
                    // We didn't receive all data. Continue reading...
                    sslStreamReader.BeginRead(stateObject.buffer, 0, stateObject.buffer.Length, new AsyncCallback(ReceiveCallback), stateObject);
                }
                else
                {
                    Console.WriteLine("We received all data. Sending response...");

                    byteData = Encoding.UTF8.GetBytes("Hello! I received your request!");

                    string httpHeaders = "HTTP/1.1" + "\r\n"
                                    + "Cache-Control: no-cache" + "\r\n"
                                    + "Access-Control-Allow-Origin: *" + "\r\n"
                                    + "\r\n";

                    byte[] byteHttpHeaders = Encoding.UTF8.GetBytes(httpHeaders);

                    byte[] concat = new byte[byteHttpHeaders.Length + byteData.Length];
                    Buffer.BlockCopy(byteHttpHeaders, 0, concat, 0, byteHttpHeaders.Length);
                    Buffer.BlockCopy(byteData, 0, concat, byteHttpHeaders.Length, byteData.Length);

                    stateObject.sslStreamReader = sslStreamReader;

                    sslStreamReader.BeginWrite(concat, 0, concat.Length, new AsyncCallback(SendCallback), stateObject);
                }
            }
        }

        private void SendCallback(IAsyncResult ar)
        {
            SslStream sslStreamSender = null;

            StateObject stateObject = (StateObject)ar.AsyncState;

            sslStreamSender = stateObject.sslStreamReader;
            sslStreamSender.EndWrite(ar);

            Console.WriteLine(stateObject.totalReceivedBytes.ToString() + " bytes sent to " + stateObject.clientIP + " address");

            sslStreamSender.Close();
            sslStreamSender.Dispose();
        }

    }

    public class StateObject
    {
        public SslStream workStream = null;

        public SslStream sslStreamReader = null;

        public const int BufferSize = 1024;
        public byte[] buffer = new byte[BufferSize];
        public StringBuilder sb = new StringBuilder();

        public string clientIP = "";

        public int totalReceivedBytes = 0;
    }
}

你的保安是对的。您尝试实现此目的的方式不适用于 SSL。

如果您有证书,则将其设置为验证一个 CN。所以,举一个过于简单的例子。谷歌有证书。它验证 https://*.google.com。这意味着对 google.com 的任何请求都会显示为具有有效证书。你的浏览器很高兴。

现在打开命令提示符,ping google.com。获取 IP 地址(在我的例子中,它是 216.58.210.14)。进入https://216.58.210.14 https://216.58.210.14。您的浏览器抱怨该网站不安全等。原因是该服务器可能与服务您之前请求的服务器相同,但根据证书,您访问该服务器的方式无效,因为 CN 不是 google。 com,而是一个IP地址。

因此,如果您有一项服务需要连接到(例如)127.0.0.1、10.92.1.4 和 myserver.com,您将需要一个对每种情况都有效的证书。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSL 认证适用于本地主机,但不适用于计算机名称或 IP 的相关文章

随机推荐

  • 从终端在 xcode PhoneGap 项目中定义方案

    我正在编写一个脚本来存档phonegap 项目的iOS 部分 该脚本会擦除项目所在的目录 然后使用源代码管理中的最新代码重新填充该目录 然后我跑 phonegap local build ios为了构建该项目 然而 为了归档该项目 我需要定
  • 在 Node.js 中生成并终止进程

    我正在尝试在 javascript 中生成一个进程 并在一段时间后终止它 出于测试目的 最后 该进程将是一个无限循环 我需要在指定时间使用不同的参数重新启动 因此我认为生成进程并终止它是执行此操作的最佳方法 我的测试代码是 var spaw
  • 用户默认值/KeyedArchiver 挫败感

    我正在开发一个作业应用程序 该应用程序为每个作业使用自定义作业对象 我试图在 standardUserDefaults 中存储 NSMutableArray 通过 initWithArray 转换为 NSArray 但在保存和重新加载数组时
  • 如何将 subversion 树从 v1.7 降级到 v1.6?

    有没有办法将 subversion 工作副本从版本 1 7 降级到版本 1 6x 版本 1 7 使用单个 svn 根文件夹和 sqlite 来存储元数据 因此 tigris org 中的转换 python 脚本不起作用 您是否知道一种不涉及
  • 如何关闭 Android 应用程序?

    如何关闭 Android 应用程序 我没有找到应用程序对象的关闭命令 我想在出现某些严重错误时关闭并重新启动 如果存在某种 严重错误 那么您应该在代码中处理它 而不是尝试重新启动应用程序 您无法关闭 Android 中的应用程序 但是一旦所
  • 如何防止光标在退出 Vim 插入模式时向后移动一个字符?

    是否可以取消上述行为 额外学分的任务 想办法强制 Vim 在退出插入模式后立即刷新光标位置 虽然我不建议更改默认的光标机制 实现相关行为的一种方法是使用以下内容 插入模式映射 inoremap
  • 绕过表单身份验证自动重定向到登录,如何?

    我正在编写一个使用 asp net mvc 部署到 iis6 的应用程序 我正在使用表单身份验证 通常 当用户尝试在未经适当授权的情况下访问资源时 我希望他们被重定向到登录页面 FormsAuth 对我来说这件事很简单 问题 现在我有一个由
  • 使用 pyqtgraph 和 LiDAR 快速实时绘制点

    我想创建一个实时的点图 GUI 我正在使用 Scanse Sweep LiDAR 每次扫描该 LiDAR 工作频率为 1 10Hz 时 我都会收到大约 1000 个描述 LiDAR 周围环境的点 x y 这是一个 2D 激光雷达 我到处寻找
  • mysql 5.6 外键约束错误; 5.5中没有出现

    涉及表 phppos permissions actions mysql gt show create table phppos permissions actions
  • Sublime Text 3 构建系统:保持控制台运行

    我在 Sublime Text 3 中设置了一个构建系统来运行 Matlab 文件 这真的很好用 cmd usr local MATLAB R2013b bin matlab nosplash nodesktop nojvm r run f
  • 获取 CN1 上没有时间的当前日期

    我在没有时间的情况下获取日期时遇到很大问题 我想将时间设置为 00 00 以便我可以检查日期差异 到目前为止我尝试的步骤 SimpleDateFormat dateFormat new SimpleDateFormat dd MM yyyy
  • 如何设置SMO ScriptingOptions以保证表的精确副本?

    我正在尝试做的事情 使用 C 创建 SQL 脚本来创建exact现有表的副本 我的问题 您将如何定义 scriptingOptions 中的选项以确保生成的脚本将创建 100 精确的表副本 有 78 个选项 目前尚不清楚如何执行此操作 最初
  • 将 ODP.NET 12 (VS2012) 连接到 Oracle 数据库 11 时出现 ORA 03134 错误

    当尝试使用 ODP NET 12 从 VS2012 连接到 Oracle 9 2 时 我收到以下消息 ORA 03134 不再支持与此服务器版本的连接 我已经安装了 ODP NET 11 但遇到了同样的错误 尽管与 Toad 的连接正常 有
  • 查询返回没有记录显示在我的网页上

    我有一个网站 我正在其中运行以下代码
  • 如何在node.js中处理stdout

    我试图自动化每次在服务器上测试应用程序和网站时所经历的过程 我目前正在nodejitsu上运行 当我测试了某些东西并且它可以在我的本地计算机上运行时 我要做的下一件事是 打开我的 package json 文件 删除域字段并将名称和子域更改
  • Spring 4 二进制文件下载

    我已经有一段时间没有下载spring了 我正在研究 gradle 但似乎还没有掌握它的窍门 所以我想使用 java Spring 4 和 ant 创建一个新的 spring 框架项目 我似乎找不到下载 Spring 4 二进制文件的地方 他
  • java.lang.ClassNotFoundException:com.mysql.jdbc.Driver。 [复制]

    这个问题在这里已经有答案了 我正在使用 Java Eclipse 连接 MySQL 数据库 但遇到以下错误 错误信息 无法连接到数据库java lang ClassNotFoundException com mysql jdbc Drive
  • 如何使用 JSON 数据递归填充 TreeView

    我有一个winforms树视图 我可以自动读取数据 一个等于key的节点 以及一个等于value的节点 但是当读取对象类型时 它里面的值不会是对象的子对象节点 对象的键 也许我无法很好地解释 这是屏幕截图和我的方法 Layer0 需要位于纹
  • 获取通用接口的所有实现类型

    我试图使用以下代码获取 IEntityModelBuilder 的所有实现 但它返回一个空集合 public class EntityFrameworkDbContext DbContext constructor s and entiti
  • SSL 认证适用于本地主机,但不适用于计算机名称或 IP

    我们有一个在服务器上运行的 Web 应用程序 它通过 XDomainRequest 发布 http 请求 因为 IE9 有很多客户端计算机都有一个控制台应用程序通过套接字侦听器侦听端口 客户打开 Web 应用程序 IE9 浏览器 当他们单击