企业自颁布服务器证书的有效性验证(C#为例)
目前根据项目的需要,整理了一下公司内部的安全通信规范,将其中涉及证书验证的部分分享出来,供探讨。
处于通信安全的考虑,很多通过互联网进行的通信,
原则上均要求使用加密通信,即采用基于SSL或TLS的安全通信。对于Web应用及Web API来说,原则上应该一律使用HTTPS,禁用HTTP;对于Socket通信来说,原则上应采用SSL协议加密传输。
基于SSL协议,需要服务器证书。对于Web应用及Web API(统称站点),原则上应使用由全球可信机构颁发的证书。但是考虑到证书费用、站点条件等一些因素,对于下列情形,可考虑使用自颁发证书:
1. 站点只在特定局域网、专网内部署使用;
2. 站点只有IP地址,没有注册域名;
3. 站点所有者不愿意支付证书费用。
若考虑企业自己建个证书颁发机构(CA),那就涉及到客户端对服务器证书的验证问题。目前很多人提到的做法都是实现自定义验证,但所谓的自定义验证就是直接返回true。这样处理,虽然能进行HTTPS加密通信,但由于实际上未对服务器证书做任何验证,因此是存在中间人攻击风险的。
本人研究了一下这个问题,发现针对.net开发,在中文网站上似乎没有很好的实现建议,因此才想到整理这篇博文和大家分享我们的做法,欢迎各位大拿批评指正。
首先,要使用自颁发证书实现HTTPS通信,最好是要对企业自己的CA做一个统一管理,CA必须具有唯一性,并且CA一旦建立,原则上应保证永不更改,从而保证企业CA的权威性。CA的权威性,是通信过程中对服务器证书进行可信验证、防止中间人攻击的基础。
其次,对自颁发证书的申请与获取,也要遵循一定的原则,主要是证书的使用者要和实际站点IP地址或域名一致,另外根据需要考虑证书有效期问题。
最后,就是在客户端对服务器证书的有效性验证了。我们将这个问题分为两部分:
(一)Web应用(网站)
对于Web应用来说,都是通过浏览器访问,而浏览器对证书的验证过程我们是无法干预的。对于自颁发证书,浏览器会提示证书无效。对于这个问题,我们的做法是参考铁总12306网站的做法:
将我们的CA证书即根证书(公钥)文件通过某种途径,发送给所有用户,要求用户将根证书安装到“受信任的根证书颁发机构”。从而防止中间人攻击。
(二)Web API
Web API均为某种客户端程序调用,调用接口需做业务权限验证。因此对于证书的验证,是在自研程序中执行。
对于自颁发证书,各研发平台的默认验证肯定是不通过的,有两种方式:
1、 跟Web网站一样,要求所有客户端设备(电脑、终端设备)均将我们的根证书安装到可信证书区域,从而可使用默认的验证方式,代码不用做任何额外处理。但这种方式,会有一定局限性,很多时候不大可行。
2、 将根证书集成到项目中,通过代码实现自定义验证。自定义验证项目包括:
a) 构建证书链,看服务器证书是否能链接到我们的根证书;这里对于不同的开发语言,处理可能不同。在C#中,需要将我们的根证书放到链引擎可搜索到的地方,然后设置合适的链策略,再重新构建证书链。
b) 上述验证通过后,验证服务器证书的使用者是否就是当前请求Uri的主机地址(IP或域名),是则通过验证;否则就是A地址的证书,用在了B地址的网站上。
服务器证书的有效期可以不用验证。由于默认的有效期是1年,如果验证有效期的话,则服务器证书每年都要更新,对于自颁发证书,没有这个必要,就让它永远有效。
如果客户端是C#,可以按如下方式进行验证:
根据项目情况做一些初始化,比如初始化根证书等。
static String caFilePath = "D:\\…….cer"; //本地根证书路径
static X509Certificate2 ca; //本地根证书对象 //验证代码一
WebRequestHandler wrh;
wrh = new WebRequestHandler();
wrh.ServerCertificateValidationCallback += RemoteCertificateValidate;
//验证代码二
ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidate;//验证服务器证书回调自动验证 if (File.Exists(caFilePath))
{
ca = new X509Certificate2(caFilePath);
}
使用该WebRequestHandler处理Https连接,以便实现自定义证书验证
HttpClient client = new HttpClient(wrh);
……
自定义验证的实现:
private bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
if (null != ca)
{
/*
* 根证书未安装到“受信任的根证书颁发机构”时,默认是无法形成可信证书链的。(chain中将只有服务器证书本身)
* 需更改链策略,然后重新构建证书链。
*/
// 将我们的根证书放到链引擎可搜索到的地方
chain.ChainPolicy.ExtraStore.Add(ca);
//不执行吊销检查
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
//忽略CA未知情况、不做时间检查
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority | X509VerificationFlags.IgnoreNotTimeNested | X509VerificationFlags.IgnoreNotTimeValid;
//重新构建可信证书链
bool isOk = chain.Build(cert as X509Certificate2);
if (isOk)
{
X509Certificate2 cacert = chain.ChainElements[chain.ChainElements.Count - ].Certificate; //获取最前面的证书,认为是根证书
//与本地根证书比较
if (ca.GetPublicKeyString().Equals(cacert.GetPublicKeyString()) && ca.Thumbprint.Equals(cacert.Thumbprint))
{
HttpWebRequest req = sender as HttpWebRequest;
if (null != req && cert.Subject.Contains("CN=" + req.Address.Host))
{
return true; //根证书可信且服务器证书确实是指定服务器的,验证通过
}
}
}
}
return false;
}
通过上述方式,可以灵活执行自定义的验证,比如既验证服务器证书确实是我们颁发给指定网站的,又可根据需要跳过证书有效性的验证。
对于在java中做自定义验证,可参考一下博文(本人没仔细研究)
http://pingguohe.net/2016/02/26/Android-App-secure-ssl.html
--------------------- 本文来自 Darlzan 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/notjusttech/article/details/72779904
企业自颁布服务器证书的有效性验证(C#为例)的更多相关文章
- APP中https证书有效性验证引发安全问题(例Fiddler可抓https包)
原文: https://blog.csdn.net/woddle/article/details/71175140 在实际项目代码审计中发现,目前很多手机银行虽然使用了https通信方式,但是只是简单 ...
- 微信支付HTTPS服务器证书验证指引
1. 背景介绍 2. 常见问题 3. 验证证书 4. 安装证书 背景介绍 微信支付使用HTTPS来保证通信安全, 在HTTPS服务器上部署了由权威机构签发的证书, 用于证明微信支付平台的真实身份. 商 ...
- Android证书有效性验证方案
1.前言: 1.1.SSL劫持攻击: 目前虽然很多Android APP使用了https通信方式,但是只是简单的调用而已,并未对SSL证书有效性做验证.在攻击者看来,这种漏洞让htt ...
- TLS就是SSL的升级版+网络安全——一图看懂HTTPS建立过程——本质上就是引入第三方监管,web服务器需要先生成公钥和私钥,去CA申请,https通信时候浏览器会去CA校验CA证书的有效性
起初是因为HTTP在传输数据时使用的是明文(虽然说POST提交的数据时放在报体里看不到的,但是还是可以通过抓包工具窃取到)是不安全的,为了解决这一隐患网景公司推出了SSL安全套接字协议层,SSL是基于 ...
- 服务器证书日期无效 SSL_DATE_INVALID
一大早上,企业微信中提示不能使用:服务器证书日期无效 错误码:SSL_DATE_INVALID 网上资料也比较少,咨询了一下企业微信客服,建议访问网址:https://www.ssllabs.com ...
- linux下安装Apache(https) 服务器证书安装配置指南
一. 安装准备 1. 安装Openssl 要使Apache支持SSL,需要首先安装Openssl支持.推荐下载安装openssl-0.9.8k.tar.gz 下载Openssl:http: ...
- https原理:证书传递、验证和数据加密、解密过程解析
写的太好了,就是我一直想找的内容,看了这个对https立马明白多了 http://www.cnblogs.com/zhuqil/archive/2012/07/23/2604572.html 我们都知 ...
- 基于iOS,Android的服务器证书失效检测
1.前言 在目前的iOS,Android手机上,当手机应用进行SSL通信时,手机端默认是不会进行服务器证书是否失效的监测. 在iOS上,系统是会定期获取所访问服务器的证书信息然后出存在本地. 在And ...
- 使用CA签发的服务器证书搭建Tomcat双向SSL认证服务
第一部分,先说证书的申请. 这步是要到正规的CA公司申请正式的设备证书必须走的步骤. 1.先生成证书的密钥对 打开命令行,切换到某个自己新建的目录下,执行如下命令 keytool -genkey -k ...
随机推荐
- 【废弃中】JavaScript 内置Object
创建: 2017/09/24 更新: 2018/01/22 增加window对象内容的链接 更改标题: [JavaScript 主要的自带Object] -> [JavaScript 内置Obj ...
- TP5之页面跳转样式
1.效果图 2.上干货 为了增加对移动设备的支持,在 /application/common.php加入以下函数: function isMobile() { if (isset ($_SERVER ...
- PV(Pageviews)、访问(Visits)和访问者(Visitors)的区别
1. 在GA上,每个页面每次加载将被记为一次PV.举例来说,一次用户访问页面顺序为:页面A->页面B->页面A,然后离开了你的站点,那这次用户访问(Visits)的PV总计为3次. 2 ...
- Metasploit工具的使用
如果有代理在前面加proxychains msfconsole 进入MSF终端search xxx xxx为要搜索的模块use xxxx 选择要用的攻击模块show options 查看相关设置set ...
- GPDB外部表创建示例
创建以|为分隔符的外部表CREATE EXTERNAL TABLE ext_expenses ( name text,date date, amount float4, category text, ...
- bzoj1475:方格取数
传送门 最小割,这也是个经典题了,当初学最小割时没学会,这次算是理解了,首先二分图染色,将整个图分成黑色点和白色点,由于相邻的格子不能同时选,一个黑点一定对应四个白点,也就是我们只能选择这个黑点或者四 ...
- android 多线程下载思路
首先请求下载url,获取文件大小和文件类型 比如获取到文件大小是7410642 文件类型为application/vnd.android.package-archive(即后缀为apk,安卓app安 ...
- python之序列化json模块与pickle模块(待补充)
一.json是所有语言都通用的一种序列化格式 只支持 : 列表,字典字符串,数字,且字典的key必须是字符串 ''' 1. dumps , loads 在内存中做数据转换: dumps : 数据类型 ...
- 利用HttpClient4访问网页
一.HttpClient介绍 虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是它没有提供足够的灵活性和其他应用程序需要的功能.HttpClient 是 Apac ...
- POJ SETI 高斯消元 + 费马小定理
http://poj.org/problem?id=2065 题目是要求 如果str[i] = '*'那就是等于0 求这n条方程在%p下的解. 我看了网上的题解说是高斯消元 + 扩展欧几里德. 然后我 ...