C# HttpWebRequest 获取 HTTPS 网页内容

2023-11-09

在 C# 中,可以使用 HttpWebRequest 类来获取 HTTPS 网页内容。需要注意的是,HTTPS 网页采用了 SSL/TLS 加密传输机制,必须在发送请求之前获取服务器端的证书并进行验证才能成功获取网页内容。下面是一份示例代码,演示如何获取 HTTPS 网页内容:

using System;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

class Program
{
    static void Main(string[] args)
    {
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
        string url = "https://example.com";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.ProtocolVersion = HttpVersion.Version11;
        request.AllowAutoRedirect = true;
        request.ContentType = "application/x-www-form-urlencoded";
        request.CookieContainer = new CookieContainer();
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {        
            Stream stream = response.GetResponseStream();
            string html = string.Empty;
            using (StreamReader reader = new StreamReader(stream))
            {
                html = reader.ReadToEnd();
                Console.WriteLine(html);
            }
        }
    }

    private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
    {
        return true; //如果不希望验证证书有效性,直接返回 true
    }
}

在上述代码中,我们首先设置了 ServicePointManager.ServerCertificateValidationCallback 回调函数,该回调函数会在服务器端的证书被验证的时候被调用,当回调函数返回 true 时,表示服务器端的证书验证通过,否则会抛出一个 SSL 异常。接下来,我们创建了一个 HttpWebRequest 构造函数,指定了要获取的 HTTPS 网页的 URL 地址,并设置了一些请求头参数。最后,我们在获取到响应流之后,读取响应流内容,并输出到控制台上。

在实际应用过程中,为了提高安全性,我们应该对服务器端证书进行验证,保证访问的网站是我们信任的网站,防止遭受网络攻击。关于验证服务器端证书需要注意以下几点:如果服务器端证书的颁发机构是受信任的颁发机构,验证可以简化为检查证书的原始日期和过期日期是否合法。你可以使用 certificate.GetExpirationDateString() 和 certificate.GetEffectiveDateString() 函数分别获取证书的原始日期和过期日期,再使用 DateTime.Parse() 函数将其转换为 DateTime 类型。
如果服务器端证书的颁发机构是自签署的或不受信任的颁发机构,那么你需要通过比较证书中的公钥和期望值来验证证书的有效性。你可以使用 certificate.GetPublicKeyString() 函数获取证书的公钥,然后与你预期的公钥进行比较。
如果你希望进一步加强服务器端证书的验证,可以通过检查证书的完整性、状态、可用性等等。可以通过 ChainPolicy() 函数来实现。
以下是一个示例,演示如何通过 ChainPolicy() 函数进行服务器端证书的验证:

private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{    
    if (errors == SslPolicyErrors.None)
    {
        return true; //如果没有 SSL 错误,直接返回 true
    }

    Console.WriteLine("Certificate error: {0}", errors);

    // 如果是自签名证书,则直接忽略错误
    if (errors == SslPolicyErrors.RemoteCertificateChainErrors && chain.ChainStatus.Length == 1)
    {
        X509ChainStatus chainStatus = chain.ChainStatus[0];
        if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot || chainStatus.Status == X509ChainStatusFlags.PartialChain)
        {
            return true;
        }
    }

    // 验证服务器端证书的完整性、状态、可用性等等
    X509ChainPolicy chainPolicy = new X509ChainPolicy();
    chainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
    chainPolicy.RevocationMode = X509RevocationMode.Offline;
    chainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
    chainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
    chain.ChainPolicy = chainPolicy;

    bool isChainValid = chain.Build((X509Certificate2)certificate);

    if (!isChainValid)
    {
        Console.WriteLine("Chain validation failed!");
        foreach (X509ChainStatus chainStatus in chain.ChainStatus)
        {
            Console.WriteLine("ChainStatus: {0} - {1}", chainStatus.Status, chainStatus.StatusInformation);
        }
        return false;
    }

    return true;
}

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

C# HttpWebRequest 获取 HTTPS 网页内容 的相关文章

  • 是否有任何替代方法来实现 WebRTC SFU,只有 1 个上传流?

    我有一个服务器 能够将 WebRTC 媒体数据从 A 中继到 B 对于视频会议 如果我们采用 P2P 方法 则会创建一个网状网络 当P2P不起作用的时候 我们就可以拥有这个中继服务器 主要问题是在网状网络中 对于N个参与者来说 上传链路的数
  • 嵌套绑定表达式

    这是一个后续问题我之前的问题 https stackoverflow com questions 2735294 templates function pointers and c0x include
  • 如何防止 Parallel.ForEach 循环在运行时更改任务数量?

    我正在使用Parallel ForEach循环做一些工作 我用localInit像这样 localInit gt new foo new Foo bars CreateBars 根据文档 https learn microsoft com
  • 无法使用VS2010 SP1进入.NET框架源代码

    我按照步骤http blogs microsoft co il blogs arik archive 2010 07 12 step into net framework 4 0 source code aspx http blogs mi
  • 委托 System.Action 不接受 1 个参数

    那个行动 readonly Action execute public RelayCommand Action execute this execute null public RelayCommand Action execute Fun
  • 如何使用 CMake 链接多个库

    我有一些与 DCMTK 相关的代码 如果我从命令行使用 g 我可以成功构建并运行它 这是代码 include dcmtk config osconfig h include dcmtk dcmdata dctk h int main Dcm
  • 对指针列表进行排序

    我再次发现自己在 C 中的一些非常简单的任务上失败了 有时我希望我能从 Java 中的 OO 中学到所有知识 因为我的问题通常是从像 Java 一样思考开始的 无论如何 我有一个std list
  • 为什么未命名的命名空间不等同于带有“using命名空间”声明的常规命名空间?

    A 最近的话题 https stackoverflow com questions 3673353 anonymous namespace ambiguityon SO 触发了这个 未命名的命名空间被认为等同于 namespace uniq
  • 从 Windows 选择声音并播放它们

    我有一个 WinForms 应用程序 该应用程序有一个 首选项 部分 用户可以在其中选择显示警报时播放哪些声音 是否可以有一个组合框 用户可以从 Windows 存储的声音中进行选择 例如 紧急停止 紧急蜂鸣 等 这些可以在 控制面板 gt
  • 静态成员函数中的封闭类的 C++ 类型

    我认为这是完全不可能的 但如果呢 在任何版本的 C 中 是否有可能以某种方式获取静态成员函数中封闭类的类型 class Impossible public static void Fun typedef Impossible Enclosi
  • 使用 C# 在 XML 文档中查找特定值的好方法是什么?

    我正在调用 Oracle 公开的 WebService 它接受 ItemID 的输入并向我返回相应的 Item Number 我想获取从响应中包含的 XML 返回的项目编号 XML 看起来像这样
  • 在多个线程中添加和删除时 List 中的 null 值

    我知道 C System Collections Generic List 对象不是线程安全的 但我想知道为什么这段代码会生成空值 Task Run gt for var i 0 i lt 10 i var str Test i list
  • 访问控制器类中的 appsettings.json 值

    无法弄清楚如何读取startup cs之外的appsettings json值 例如 我想做的是在 Layout cshtml 中 从配置中添加站点名称 例如 ViewData SiteName Configuration GetValue
  • 获取上下文菜单的控制

    我有一个如下所示的上下文菜单 A 1 2 3 选择 1 2 或 3 后 我需要访问调用上下文菜单的对象 意思是如果这是 textbox1 的上下文菜单 那么我需要访问该对象 我该怎么做 忘了说了 这是一个WPF应用程序 所以我使用 Syst
  • 我如何在 WPF 中模仿这种行为?

    我对 WPF 和 C 开发相当陌生 我正在制作这个应用程序 我不知道是否有人熟悉 VOIP App Discord 但他们有一个我非常喜欢的特定行为 并且想尝试使用 WPF 创建类似的风格 当您在 Discord 上添加服务器时 单击一个按
  • 如何在迭代时从地图中删除?

    迭代时如何从地图中删除 喜欢 std map
  • 如何在 C 中将 int 和数组保存在共享内存中?

    我正在尝试编写一个程序 让子进程在 Linux 上相互通信 这些进程都是从同一个程序创建的 因此它们共享代码 我需要它们能够访问两个整数变量以及一个整数数组 我不知道共享内存是如何工作的 我搜索过的每一个资源除了让我困惑之外什么也没做 任何
  • 类型与创建 CLR 存储过程不匹配

    我在程序集中有一个如下所示的方法 namespace MyNameSpace public class MyClass Microsoft SqlServer Server SqlProcedure public static void M
  • 系统.安全.加密与 PCLCrypto

    我们正在删除系统中的许多共享功能并将其移植到 PCL 库中 我在使用 PCLCrypto 时遇到问题 我正在获取数据库中的一些现有数据 并尝试使用相同的算法对其进行解密 我得到了值 但末尾有 16 个额外字节 这些字节都是垃圾 参见下面的代
  • 从 C# 调用 C++ DLL

    我想使用 C 中的 C DLL C DLL 是win32 控制台应用程序 我已成功调用它 并希望在 C 中处理来自 C 的数据 然而 C 应用程序在执行 DLL 后退出 即这一行 GetArrayFromDLL 我是 C 和 Visual

随机推荐

  • shell case语句及函数

    case 菜单选择打印 语法 case var in var变量 patten 1 匹配模式1 a b c 和or类似 command 需要执行的命令 命令执行完毕 patten 2 command 默认值 没有匹配的模式 command
  • 【java】java中解决线程安全问题的三种方法

    java中解决线程安全问题的三种方法 当我们使用线程进行卖票时会出现诸多的安全问题为了解决这种情况 有三种方法可以进行选择 第一种是同步代码块 第二种是同步方法 第三种是Lock锁 在没有用的解决安全问题的时候会出现以下问题 测试类 pub
  • IIS7.0、7.5解析漏洞利用

    IIS7 0 7 5解析漏洞利用 1 测试漏洞是否可用 2 WebShell制作 3 上传WebShell 4 连接WebShell 1 测试漏洞是否可用 网站任意图片地址后加 脚本类型 若出现编译错误 则漏洞存在 2 WebShell制作
  • AI对游戏外包开发的影响

    人工智能 AI 对游戏行业产生了深远的影响 从游戏设计 开发到玩家体验等方面都发挥着重要作用 以下是AI对游戏行业的一些主要影响 和大家分享一些观点 希望对大家有所帮助 北京木奇移动技术有限公司 专业的软件外包开发公司 欢迎交流合作 1 游
  • 使用Vlc.DotNet打开摄像头并截图 C#

    参考上一篇 使用vlc打开usb摄像头 理论上输入下面地址 dshow dshow size 1600 1200 dshow vdev USB CAM2 C 就能打开摄像头了类似打开本地文件或者rtsp之类的网络地址 但实际测试怎么着都是打
  • 计算机网络复习4----TCP的拥塞窗口cwnd大小与传输轮次n的关系

    这里是 凤凰谷佛的计算机网络复习系列之4 一起来看看吧 书中P236 图5 27 1 5 39 TCP的拥塞窗口cwnd大小与传输轮次n的关系如下所示 试分析回答 1 指明TCP工作在慢开始阶段的时间间隔 解析 满开始时间间隔看在哪一刻2倍
  • traits:Traits技术初探

    概述 traits是一种特性萃取技术 color 663300 font family 宋体 padding 0px margin 0px gt 它在Generic Programming中被广泛运用 常常被用于使不同的类型可以用于相同的操
  • PHP文件包含漏洞代码分析-通过漏洞getshell-学习笔记

    一 原理分析 文件包含漏洞是代码注入的一种 其原理就是注入一段用户能控制的脚本或代码 并让服务器端执行 代码注入的典型代表就是文件包含 File inclusion 文件包含可能会出现在jsp php asp等语言中 服务器通过函数去包含任
  • Python笔记4

    迭代器 迭代是Python最强大的功能之一 是访问集合元素的一种方式 迭代器是一个可以记住遍历的位置的对象 迭代器对象从集合的第一个元素开始访问 直到所有的元素被访问完结束 迭代器只能往前不会后退 迭代器有两个基本的方法 iter 和 ne
  • css flex布局 —— 项目属性 align-self

    align self属性定义 flex 子项单独在侧轴 纵轴 方向上的对齐方式 可覆盖 align items 属性 默认值为 auto 表示继承父元素的 align items 属性 如果没有父元素 则等同于 stretch 语法 ite
  • 实战--Kafka入门(一)

    问题导读 1 如何理解消息队列 MessageQueue 2 如何解析Kafka基础架构 3 如何安装Kafka集群 4 Kafka命令行操作有哪些 第1章 Kafka概述1 1定义 Kafka是一个分布式的基于发布 订阅模式的消息队列 主
  • 关于野指针的一些问题与总结

    void Test void char str char malloc 100 strcpy str hello free str if str NULL strcpy str world printf str 请问运行Test函数会有什么
  • 在闲鱼上卖什么东西比较赚钱?

    在闲鱼上卖什么东西比较赚钱 这牵扯做闲鱼的一个关键问题 选品 可以这么说 会选品 选好品 就成功了一半 剩下的一半 一半交给技术 另一半交给运气 怎么选品 要遵循下面几个原则 第一 做实物 但不要做食物 不要去做虚拟产品 也不要去做生鲜食物
  • 查看YOLO的模型大小和参数量的三种方式

    查看YOLO的模型大小和参数量的三种方式 1 使用Darknet YOLO的原始实现 2 使用Python和深度学习库 3 使用PyTorch 要查看YOLO模型的大小和参数量 你可以使用相关的深度学习库和工具 比如TensorFlow P
  • Centos7/SSH Weak Key Exchange Algorithms Enabled/SSH Server CBC Mode Ciphers Enabled

    SSH Weak Key Exchange Algorithms Enabled SSH Server CBC Mode Ciphers Enabled https knowledge broadcom com external artic
  • 中文乱码解决大全

    一 Java中文问题的由来 Java的内核和class文件是基于unicode的 这使Java程序具有良好的跨平台性 但也带来了一些中文乱码问题的麻烦 原因主要有两方面 Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交
  • data must not be longer than 256 bytes

    1 问题 在进行 RSA 解密时候报错 data must not be longer than 256 bytes 2 分析 RSA加解密算法通常有两种不同的方式 是使用对称密钥 比如 AES DES等加解密方法 加密数据 然后使用非对称
  • JSP简单练习-一个简单的计数器

    在JSP中 在 之间书写的程序代码成为java程序片 一个JSP页面中可以有多个java程序片 要注意的是 在Java程序片中声明的变量在它们所在JSP页面的所用程序片及表达式中都有效 基于此 可以把一个较大的程序片分成几个小的程序片 还可
  • python 作图中的图标题title 和坐标轴标签的axes的调整

    这里主要是调整title和坐标轴标签的样式 要注意抓住设定的套路和规律 不要被复杂的外表所迷惑 import matplotlib pyplot as plt import numpy as np from matplotlib impor
  • C# HttpWebRequest 获取 HTTPS 网页内容

    在 C 中 可以使用 HttpWebRequest 类来获取 HTTPS 网页内容 需要注意的是 HTTPS 网页采用了 SSL TLS 加密传输机制 必须在发送请求之前获取服务器端的证书并进行验证才能成功获取网页内容 下面是一份示例代码