C#.Net中的加密解密(AES、DES、RSA、MD5)、数字证书、HTTPS

一、信息安全的基本概念,以及为什么要使用加密?

1、信息安全的定义

保密性(Confidentiality) 
只有你自己和你允许的人能看到相关的信息。 

完整性(Integrity) 
信息收发过程中没有被破坏或篡改过。

可获得性(Availability) 
自己在需要的时候能够访问到信息或者保证对方能够收到你的信息。 

2、如何保证安全

认证(Authentication) 
认证就是证明你就是那个你所声称的那个人。举个例子,比如你去机场登机,你必须出示身份证才能证明你自己。在信息安全领域也一样,比如你想去Google查看张一山的邮件,然后google会问你要张一山的密码,因为只有张一山知道张一山帐户的密码,如果你能说出那个密码,那么你就是张一山,google就会把张一山的邮件返回给你。这个过程也被称为Identification。 

授权(Authorization) 
授权是指一个系统里面有很多用户,有些用户能做某些事情,有些用户不能做某些事情。比如Linux,很多用户可以同时通过认证而登录到Linux主机,但是只有root才能修改或删除系统文件,普通用户只能修改自己的home。 

3、为什么要使用加密

计算机世界是基于网络的,根据目前网络的结构和实现,请求数据包在世界各地的路由器之间游荡,任何人都可以获得你的发送的数据包,从而获得你发送的数据。比如当你访问一个HTTP网站时,你发出去一个请求,路由器会把请求广播给离目的地更近的路由器,可能是一个路由器,也可能是多个路由器。也就是说在这个请求到达目标服务器的路途上,不管是你家的路由器、你楼层的路由器、你小区的路由器、你当地电信的机房里,再一直到那个网站的服务器机房之间的所有网络设备上,都有你请求的数据通过。一般情况下,只有一份数据会被目的计算机接收到,其他的拷贝在网络上游荡一段时间以后就被抛弃了。但是只要中间有任何一个设备想要把数据记录下来,它可以没有任何阻力的做到,因为这些数据是完全可见、没有经过任何混淆和加密的。正是因为网络有这样的问题,人们就发明了很多加密通信的手段,来保证自己的通信的内容不会被泄露。比如SSL、数字证书、以及使用HTTPS协议都是为了保证数据的安全,这些方式都是基于加密的,对信息的加密是需要加密算法的,基本上要破解一个加密算法是非常非常困难的,至少目前流行的加密算法还是安全的。

二、单向散列算法(Hash)、对称加密

  • 单向散列算法MD5(Hash)

MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2、MD3和MD4发展而来。MD5算法的使用不需要支付任何版权费用。虽然Hash不只是MD5,常见的还有SHA1,不过MD5最流行,所以一般大家说的Hash就是它了。Hash就是一个工具,它能把任意大小的文档变成一个 固定大小(MD5是32个字符)的字符串,如果小于32个字符,比如16个字符都是从32个字符中截取的。并且,这个过程是 不可逆的,也就是说,没有任何办法从那个字符串得到原来那个文档。

C#.Net中的加密解密(AES、DES、RSA、MD5)、数字证书、HTTPS_第1张图片

MD5属不属于加密算法:认为不属于的人是因为他们觉得不能从密文(散列值)反过来得到原文,即没有解密算法,所以这部分人认为MD5只能属于算法,不能称为加密算法;认为属于的人是因为他们觉得经过MD5处理后看不到原文,即已经将原文加密,所以认为MD5属于加密算法,看你们个人理解吧。

MD5的用途:1)、很常见的应用就是为了防止用户密码泄露,密码用MD5加密后保存到数据库,用户在登陆后将输入的密码进行MD5加密后再做比对。2)、SVN在检测文件是否在CheckOut后被修改过,也是用到了MD5。3)提供文件下载时,为了防止不法分子在安装程序中添加木马,可以把文件MD5后的结果放上去,用户下载文件后将文件进行MD5加密进行比对即可。

注意:虽然MD5不能反向推导出明文,但是MD5用做上诉密码的加密其实是不太安全的,毕竟很多用户习惯用生日、姓名拼音等及其简单的方式当作密码。目前已有人通过穷举字符组合的方式,创建了明文密文对应查询数据库来破解密码,例如 此网站。


  • 对称加密(Symmetric Cryptography)

所谓加密就是把一段能看懂的东西通过某种变换变成看不懂的东西,当然这种变换是可逆的,这里所说的“变换”就是加密算法。目前我们所说的加密算法基本上都是基于密钥的,加密算法不能单独工作,必须有密钥配合,加密的算法是公开的,大家都可以用此算法,但密钥是保密的。虽然我们平时一般说“加密算法”,但往往这个加密算法都包含解密算法的。人们对于哪一种加密方法更安全还存在争论,但是目前的分组密码都比序列密码要更安全一点。在实际运用中最常被使用的是分组密码。其中应用最广泛的就是高级加密标准(AES)

1977年,美国标准局(NBS)发布了数据加密标准(DES),并且在20年内都是美国政府所使用的标准加密方式。随着计算能力的大幅度提高,2000年,美国国家标准与技术研究院发布了高级加密标准(AES)。AES至今仍然是最强大的对称加密算法,目前还不存在从技术上有效破解AES的方法。关于AES算法的具体实现细节,有兴趣者可以下载官方的AES标准(FIPS PUB 197)[2]

 “对称加密”是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,比较流行的有DES,AES,Blowfish等,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率。

举个例子,你想发公司工资列表给你朋友,但是你不想让别人看见所以你选择AES加密,这个AES用的密钥是你和你朋友事先约定的,只有你们两个人知道。在发送之前,你用AES算法和约定好的密钥给列表文档加密,然后把加密过的文档发送给你的朋友。你朋友收到以后可以用AES算法和那个密钥解密而获得原始的文档。 对称加密算法的优点是速度快,缺点是密钥管理不方便,要求共享密钥,换句话说,如何把密钥发送到需要解密你的消息的人的手里是一个问题。在发送密钥的过程中,密钥有很大的风险会被黑客们拦截。现实中通常的做法是将对称加密的密钥进行非对称加密,然后传送给需要它的人,具体操作在下面的非对称密钥中会讲到。

C#.Net中的加密解密(AES、DES、RSA、MD5)、数字证书、HTTPS_第2张图片

AES加密标准文件:https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf

对称加密存在这样两个问题:

虽然可以通过密钥来保证消息安全地进行传递,但是如何确保密钥安全地进行传递?因为发送者和接收者总有一次初始的通信,用来传递密钥,此时的安全如何保证?

接收者虽然可以根据密钥来解密消息,但因为存在上面的问题,消息有可能是由第三方(非法获得密钥)发来的,而接收方无法辨别。

举例说明:你向银行发送卡号密码等信息,你如果明文发送就太不安全了,如果你要加密后发送,你不知道密钥是多少,假如这个时候银行给你传回来加密的密钥,这个密钥很容易就会被第三方获取到,就可以解密用户加密过的银行卡信息。

三、非对称加密

  • 数学魔术

小时候我的同学小明给我表演过这样的魔术:让我任意想一个三位数,然后把这个三位数乘以91,最后把乘积的末尾三位告诉他。我想到了123这个数,乘以91得到了11193,接着我去掉两位只保留后三位,把193告诉了他。结果他很快地说出我心里想的数是123。这个魔术的解法其实很简单:小明知道我的结果193后,再用193乘以11,得到了2123。而2123的末尾三位数,就是我的想的123。

原理也很简单,因为91乘以11等于1001,而任意一个三位数乘以1001,乘积的末尾三位一定等于它本身。我在进行了123 * 91操作后,小明进行了乘以11操作,即整个步骤为123 * 91 * 11 == 123 * 1001。而中间有一次去掉前两位仅保留后三位的操作(除以1000取余),看似丢失了信息量,实际上对结果毫无影响。其中的数学原理是:如果最后要对乘积取余,那么在事先对乘数取余不会对结果造成影响。而我的同学小张即使听到了小明告诉我:把心里想的三位数乘以91,和我告诉小明:结果末尾三位是193,也没办法解开我心里想的数。

假如小张长大了,考上大学的小张会知道上面得到91和193后,要做的其实是解一个方程:91 * x mod 1000 = 193。有这样一个原理:ab互质,且a * x mod b = c,那么a * n * x mod b = n * c。这时他迅速地算出91 * 11 mod 1000 = 1,那么91 * 11 * 193 mod 1000 = 193。就是说11 * 193 mod 1000 = 123,一定等于我想的三位数。

这个魔术的步骤已经几乎满足了非对称加密的全部要素!失败之处在于,通过91(公钥)还是可以很容易的得到11(私钥)和加密信息的解。

  • 非对称加密

对称加密的弊端就是加密解密的密钥相同,但是在某些应用中,我们不希望一个人同时掌握加密和解密的能力,或者是害怕加密或解密的一方泄露了密钥。

非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。非对称加密算法的密匙是通过一系列算法获取到的一长串随机数,通常随机数的长度越长,加密信息越安全。通过私钥经过一系列算法是可以推导出公钥的,也就是说,公钥是基于私钥而存在的。但是无法通过公钥反向推倒出私钥,这个过程的单向的。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥常用的非对称加密算法有RSA,ECC等等比如,你向银行请求公钥,银行将公钥发给你,你使用公钥对消息加密,那么拥有私钥的银行才能对你的消息解密。与对称加密不同的是,银行不需要将私钥通过网络发送出去,因此安全性大大提高。

虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。为了解释这个过程,请看下面的例子:

(1) Robin需要在银行的网站做一笔交易,他首先生成了一个随机数作为对称密钥,然后向银行请求公钥, 银行将公钥发送过来。

(2) Robin使用银行的公钥将自己的对称密钥进行加密,并且用对称密钥把消息进行加密,然后一并发送给银行。

(3) 银行使用私钥解密得到Robin的对称密钥。然后通过对称密钥解密消息。

 

综上所述,对称加密和非对称加密各自的优缺点如下:

对称加密:

优点:算法简单,加密解密容易,效率高,执行快。

缺点:相对来说不算特别安全,只有一把钥匙,密文如果被拦截,且密钥也被劫持,那么,信息很容易被破译。

非对称加密:

优点:安全,即使密文被拦截、公钥被获取,但是无法获取到私钥,也就无法破译密文。作为接收方,务必要保管好自己的密钥。

缺点:加密算法及其复杂,安全性依赖算法与密钥,而且加密和解密效率很低。

RSA原论文:https://people.csail.mit.edu/rivest/Rsapaper.pdf

四、中间人劫持

如果没有中间人劫持的话,这篇文章应该就结束了。

毕竟上面的方案看起来已经很完美了,但是事实就是,有这么一种攻击方案可以轻松的突破这一套体系:

  • 你和服务器之间有一台邪恶的路由器XE
  • 当你给网站的服务器发请求后,网站带着公钥EN响应你
  • 响应到达XE,XE拿到了EN,但是并不把它交给你,而是自己伪造了一对公私钥XE_EN和XE_DE,并把XE_EN给你
  • 你拿到XE_EN,以为是网站的公钥EN,用它加密了Mes,再请求网站
  • 请求到达XE,XE使用XE_DE解开Mes,再用EN加密Mes交给网站

没错,就这样,邪恶路由器得到了你要发送的数据Mes。为了解决这个问题,又引入了数字签名和数字证书。

五、数字签名和数字证书

数字签名

 数字签名所用的技术是散列和非对称加密。数字签名的假设是: 只有你自己有你的私钥。根据前面对散列的介绍,举例如下:甲要发送消息给乙,乙方先生成一对非对称加密钥,把公钥给甲,甲先把消息通过Hash算法MD5得到Hash1的值,然后通过乙给过来的公钥加密得到密文,然后把消息和密文一并发给乙。乙接收到过后,先用自己的私钥解密出密文,得到Hash1,然后通过把消息通过Hash算法MD5得到Hash2的值,通过对比Hash1和Hash2是否相等来判断消息是否被篡改。也就是说,数字签名能够验证收到的信息的完整性,避免中途信息被劫持篡改或丢失。对方可以根据数字签名来判断获取到的数据信息是否是最原始的数据。

或许你在想,为什么要对Hash加密呢?我直接对文档用我的私钥加密不就完了嘛?对啊,效果是一样的,但是效率不一样哦~别忘了非对称算法是很慢的,加密一个100M的文件要算半天呢!

数字签名实际上就是上面非对称加密的认证模式,只不过做了一点点的改进,加入了散列算法。大家比较熟悉的散列算法可能就是MD5了,很多开源论坛都采用了这个算法。散列算法有三个特点:一是不可逆的,由结果无法推算出原数据;二是原数据哪怕是一丁点儿的变化,都会使散列值产生巨大的变化;三是不论多么大或者多么少的数据,总会产生固定长度的散列值(常见的为32位64位)。产生的散列值通常称为消息的摘要(digest)。上面举例的非对称加密算法,只是对消息摘要进行了加密,而没有对消息本身进行加密。非对称加密是一个非常耗时的操作,由于只对消息摘要加密,使得运算量大幅减少,所以这样能够显著地提高程序的执行速度。同时,它依然没有确保消息不被第三方截获到,不仅如此,因为此时消息是以明文进行传递,第三方甚至不需要发送方的公钥,就可以直接查看消息。

这里要顺便提一下消息认证码( Message Authentication Code)。 它和数字签名很相似,只不过它是用对称加密的而数字签名用的是非对称加密。

在现实生活中,各种加密手段往往是配合使用以达到最好的效果和效率。比如我将要介绍的SSL和数字证书,就是混合了各种的加密手段。

 

高级实现

发送方所执行的步骤:

将消息进行散列运算,得到消息摘要。

使用自己的私钥对消息摘要加密(认证模式:确保了接收方能够确认自己)。

使用接收方的公钥对消息进行加密(加密模式:确保了消息只能由期望的接收方解密)。

发送消息和消息摘要。


接收方所执行的步骤:

使用发送方的公钥对消息摘要进行解密(确认了消息是由谁发送的)。

使用自己的私钥对消息进行解密(安全地获得了实际应获得的信息)。

将消息进行散列运算,获得消息摘要。

将上一步获得的消息摘要 和 第一步解密的消息摘要进行对比(确认了消息是否被篡改)。

 

可以看到,通过上面这种方式,使用了接收方、发送方全部的四个密钥,再配合使用消息摘要,使得前面提出的安全传递的所有三个条件全都满足了。那么是不是这种方法就是最好的呢?不是的,因为我们已经说过了,非对称加密是一种很耗时的操作,所以这个方案是很低效的。实际上,我们可以通过它来解决对称加密中的密钥传递问题,如果你已经忘记了可以翻到前面再看一看,也就是说,我们可以使用这里的高级实现方式来进行对称加密中密钥的传递,对于之后实际的数据传递,采用对称加密方式来完成,因为此时已经是安全的了。

 

证书机制

在上面的各种模式中,我们一直使用了这样一个假设,就是接收方或者发送方所持有的、对方的公钥总是正确的(确实是对方公布的)。而实际上除非对方手把手将公钥交给我们,否则如果不采取措施,双方在网络中传递公钥时,一样有可能被篡改。那么怎样解决这个问题呢?这时就需要证书机制了:可以引入一个公正的第三方,当某一方想要发布公钥时,它将自身的身份信息及公钥提交给这个第三方,第三方对其身份进行证实,如果没有问题,则将其信息和公钥打包成为证书(Certificate)。而这个公正的第三方,就是常说的证书颁发机构(Certificate Authority),简称为:CA数字证书绑定了公钥及其持有者的真实身份,它类似于现实生活中的居民身份证,所不同的是数字证书不再是纸质的证照,而是一段含有证书持有者身份信息并经过认证中心审核签发的电子数据,当我们需要获取公钥时,只需要获得其证书,然后从中提取出公钥就可以了。

中间人能劫持成功的本质,还是因为链路是不安全的。所以没有被加密的握手过程一定会有这个问题。简单来说,一个HTTPS网站响应给我们的并不是一个公钥,而是证书。证书上包含了公钥,还包含了域名、签发机构、有效期、签名等等。那证书的安全性怎么保证?为什么中间人不能做一个假证书?因为这套证书体系已经根植于每一个操作系统里了。每一个操作系统里,都内置了数十张根证书,每个根证书都对应一个非常权威的证书签发机构。这些根证书上记录了各个机构的公钥。当网站找证书机构购买了一份合法的证书时,网站申请的证书上的公钥、域名、有效期等信息会被计算一次hash,然后证书机构用它的私钥给这个hash加密一次。这个加密结果就是证书的签名。

当网站的合法HTTPS证书到达你的电脑上,这个证书上带有签发机构的信息(具体来说应该是一条证书链),你的浏览器会用这个签发机构对应的操作系统内置根证书上的公钥,去解开网站HTTPS证书的签名(还记得吗,由于运算结果有周期性,所以用私钥加密的信息可以用公钥解开)。发现签名解开的hash与证书信息内容的hash一致,就可以证明证书是合法的了。举例如下:

比如百度向CA机构申请一张证书,在申请的时候,会提交一些自己的信息。比如公司名称叫百度,域名是www.baidu.com,还会自己生成一对非对称加密钥,然后把公钥也给到CA。然后CA机构会给百度公司颁发一张证书,这张证书包含信息如下:1)证书持有人姓名  2)发证机关  3)证书有效日期  4)证书持有人的公钥  5)扩展信息  6)数字签名

数字签名=前5点信息MD5后为Hash1的这个摘要,然后CA也有一对自己的非对称加密的钥匙,CA把自己的私钥加密Hash1。

百度呢就把这个证书安装在自己的服务器上。客户端(用户)第一次在发送HTTPS请求服务器的时候,服务器就会返回这个证书,客户端安装这个证书到浏览器,浏览器通过识别证书确认用户访问的就是百度,这样就安全了,这也就是我们的HTTPS协议。

 

C#.Net中的加密解密(AES、DES、RSA、MD5)、数字证书、HTTPS_第3张图片

那中间人能不能申请一个真的证书然后去做劫持呢?

通常来说,证书签发机构的审核非常严格,如果无法证明www.zhihu.com这个域名属于他,签发机构是不会给他签发一个知乎域名的证书的。而如果中间人用了其他域名的证书,浏览器会发现你请求的域名和返回的证书不一致,从而拒绝继续请求。除非你一定要点下面的页面上「仍然继续」按钮进入非法网站。

六、SSL、HTTPS

HTTPS是HTTP+SSL,HTTPS经过SSL证书进行加密,是HTTP的加密版本。经过SSL加密向服务器传输的数据,比如用户名和密码都是经过加密,无法被窃取和篡改。在很多大型网站会采用HTTPS,广泛用于电商网站、支付、金融等高私密性网站。

刚才上面的证书机制没讲完,那浏览器到底是如何识别证书确认网站是合法的呢?还是说到百度申请好了CA证书,用户在请求百度网站的时候也安装了这个证书,浏览器在发送请求给服务器的时候去CA证书里去找这个证书的发证机关。前面也说了浏览器都会自己内置一级跟证书,也就是发证机关,这些根证书里面都带有发证机关对外开放的非对称加密的公钥,这个公钥就是解密钥,用这个解密钥就可以解密百度申请的CA证书中的数字签名。解密出来得到MD5摘要,再把摘要信息进行哈希运算,然后跟MD5摘要进行比对,来确保CA摘要信息没有被篡改,也就是这个百度的CA证书是合法的。确认证书合法后,浏览器再用百度证书里面百度公开的公钥加密一条信息,然后发送给服务器,服务器如果解密出来了那就证书服务器就是百度,这个操作是浏览器自己操作的,不是开发要做的。然后客户端就可以把对称加密的key通过百度的非对称加密的公钥也就是百度CA证书的公钥进行加密发送给服务器,这样就可以安全的发送消息了。

C#.Net中的加密解密(AES、DES、RSA、MD5)、数字证书、HTTPS_第4张图片

 

网站使用HTTPS有什么优势?

安全性方面:

1、HTTPS协议可以认证用户和服务器,保证客户端和服务器端之间的数据传输安全。

2、HTTPS通过SSL证书+HTTP协议进行加密传输、身份认证的一种网络通信协议,对比HTTP 超文本传输协议安全性高,HTTPS具有加密传输通道,有效保障隐私数据密文传输,截取也无法解密。

3、HTTPS具有防范钓鱼电子邮件一般含有恶意链接,引诱用户访问克隆网站。

网站收益方面:

1、网站更安全,保障用户隐私信息安全

HTTPS在数据传输的过程中,可以确保用户数据不被劫持。

2、提升企业品牌形象和用户的可信度

如果在登录的界面无需验证就直接登录,用户会觉得该网站信息是否会存在泄漏的风险。如果网站安装了SSL证书,使用个人信息来登录,有效保障你登录电商网站支付时提交的用户名密码的安全。

3、用户轻松验证网站真实身份

网站安装SSL证书,浏览器会设置安全机制,用户通过浏览器了解网站的认证信息,用户能判断网站的真实身份。

4、有使用HTTPS的网站,在搜索展示端会出现HTTPS的展现样式。

5、网站使用HTTPS有助于SEO优化,保证了网站传输数据的安全性,也可以提升网站的信任度。

HTTPS的缺点:

1、SSL的证书是需要购买的,功能越强大的证书费用越高。

2、HTTPS连接缓存会增加数据开销和功耗。

3、SSL证书只能绑定一个IP上,不支持绑定多个域名。

 

你可能感兴趣的:(.NET高级开发)