HttpWebRequst中https的验证处理问题
最近在公司项目中使用了HttpWebRequst相关API,运行环境为.Net/Mono 2.0,是一款针对Unity平台的工具。开发过程中碰到了大家可能都碰到过的问题,Http还是Https? 为什么Http可以正常响应,Https就会失败,返回结果为authorize or decrypt failed.
by th way, .Net 4.0及以上版本好像已经没有这个问题了,巨硬默默把坑填了。
使用Http的写法:
public void Get(string Url) { HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (Url); webRequest.Method="GET"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"; webRequest.BeginGetResponse(GetResponseCallback,webRequest); } private void GetResponseCallback(IAsyncResult ar) { //RequestState myRequestState = (RequestState)ar.AsyncState; HttpWebRequest webRequest = (HttpWebRequest)ar.AsyncState; try{ WebResponse response = webRequest.EndGetResponse(ar); streamReader = new StreamReader(response.GetResponseStream ()); } catch(Exception es) { Debug.Log (es.Message); } if (GetDataCompleted != null) { GetDataCompleted(this,new GetDataCompletedArgs(streamReader.ReadToEnd ())); } }
这里使用了异步,同步的写法效果相同。
但是如果此时使用了Https的Url,结果会一直返回失败。这是为什么呢?原因是Https基于SSL/TLS协议,需要在请求之前进行证书验证,而我们上面的写法并没有进行相关的验证,所以导致通信失败。怎么解决此问题呢?很简单,我们在请求发出前进行验证,在.Net 2.0或更高版本,我们加入回调函数即可。
解决办法:
public void Get(string Url) { //SSL/TLS certificate method ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (Url); webRequest.Method="GET"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"; webRequest.BeginGetResponse(GetResponseCallback,webRequest); } /// <summary> /// SSL/TLS certificate callback method /// Must return true /// </summary> /// <returns><c>true</c>, if validation result was checked, <c>false</c> otherwise.</returns> /// <param name="sender">Sender.</param> /// <param name="certificate">Certificate.</param> /// <param name="chain">Chain.</param> /// <param name="sslPolicyErrors">Ssl policy errors.</param> public bool CheckValidationResult (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) { //Debug.LogWarning (certificate.GetSerialNumberString ()); return true; } /// <summary> /// Gets the response callback. /// </summary> /// <param name="ar">Ar.</param> private void GetResponseCallback(IAsyncResult ar) { //RequestState myRequestState = (RequestState)ar.AsyncState; HttpWebRequest webRequest = (HttpWebRequest)ar.AsyncState; try{ WebResponse response = webRequest.EndGetResponse(ar); streamReader = new StreamReader(response.GetResponseStream ()); } catch(Exception es) { Debug.Log (es.Message); } if (GetDataCompleted != null) { GetDataCompleted(this,new GetDataCompletedArgs(streamReader.ReadToEnd ())); } }
至此就可以,解决此问题,这类问题说大不大,说小不小,属于我们开发中遇到的小坑之一,.Net4.0以上版本不需注意此问题。
关于更低的.Net 1.1的写法,大家可以去看一下博客,本篇博文也是参照他的解决方案:
http://blog.sina.com.cn/s/blog_4ae95c270101qnn1.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?