- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
上一篇噢,我们搞明白了什么是安全的通信,这个很重要,特别重要,敲黑板!! 。
然后,我们还学了HTTPS到底是什么,以及HTTPS真正的核心SSL/TLS是什么。最后我们还聊了聊TLS的实现,也就是OpenSSL.
那么这一篇,就会稍微长一点了,很重要!我们来聊一聊,安全的四大特性是如何被TLS实现的.
说起机密性,不知道大家第一时间是不是跟我想的一样。加密呗。一点毛病没有~就是加密。加密说白了就是把谁都能看的懂的内容,转换成只有拥有 钥匙 的人才看的懂的内容。这里的“钥匙”就叫做“ 密钥 ”(key),加密前的消息叫“ 明文 ”(plain text/clear text),加密后的乱码叫“ 密文 ”(cipher text),使用密钥还原明文的过程叫“ 解密 ”(decrypt),是加密的反操作,加密解密的操作过程就是“ 加密算法 ”.
所有的加密算法都是公开的,任何人都可以去分析研究,而算法使用的“密钥”则必须保密.
那么,这个关键的“密钥”又是什么呢?
由于 HTTPS、TLS 都运行在计算机上,所以“密钥”就是一长串的数字,但约定俗成的度量单位是“位”(bit),而不是“字节”(byte)。比如,说密钥长度是 128,就是 16 字节的二进制串,密钥长度 1024,就是 128 字节的二进制串.
按照密钥的使用方式,加密可以分为两大类: 对称加密 和 非对称加密 .
对称加密很好理解,就是指加密和解密都是使用的同一个密钥,是”对称“的。只要保证了密钥的安全,那整个通信过程就可以说具备了机密性.
举个例子,你想要登录某个网站,只要事先与它约定好使用一个对称密钥,通信过程中全是用密钥加密后的密文,只有你和网站才能解密,黑客即使能够窃听,看到的也是乱码,因为没有密钥无法解出明文,所以就实现了机密性.
这图片我复制过来的~懒得画了,哈哈哈.
TLS 里有非常多的对称加密算法可供选择,比如 RC4、DES、3DES、AES、ChaCha20 等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有 AES 和 ChaCha20 .
AES 的意思是“高级加密标准”(Advanced Encryption Standard),密钥长度可以是 128、192 或 256。它是 DES 算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法.
ChaCha20 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,曾经在移动客户端上比较流行,但 ARMv8 之后也加入了 AES 硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错的算法.
所以,总结下来,我们只要知道 TLS最常用的对称加密算法就是AES ,其它的加密算法要么不安全,要么就跟AES差不多.
对称加密还有个” 分组模式 “的概念,它可以让算法用固定长度的密钥加密任意长度的明文.
最早有 ECB、CBC、CFB、OFB 等几种分组模式,但都陆续被发现有安全漏洞,所以现在基本都不怎么用了。最新的分组模式被称为 AEAD (Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是 GCM、CCM 和 Poly1305 .
把上面这些组合起来,就可以得到 TLS 密码套件中定义的对称加密算法.
比如,AES128-GCM,意思是密钥长度为 128 位的 AES 算法,使用的分组模式是 GCM;ChaCha20-Poly1305 的意思是 ChaCha20 算法,使用的分组模式是 Poly1305.
对称加密看上去好像还不错,但是其中有一个很大的问题,就是通信的双方如何安全的把密钥传递给对方,术语叫做” 密钥交换 “.
因为再对称加密算法中,密钥成了密文的关键,只要持有密钥,就能解密密文获得明文数据。虽然黑客无法直接解密传输过程中的密文,但是可以拦截捕获传输过程中传递的密钥,那他就可以在之后随意解密收发的数据,通信过程也就没有机密性可言了.
怎么解决这个问题呢,嗯……那就再把密钥也加密一下,但是传输加”密密钥的密钥“又出现了同样的问题,得~~这样不就死循环了?所以,只用对称加密算法,是绝对无法解决密钥交换的问题的.
所以,就出现了非对称加密(也叫公钥加密算法).
它有两个密钥,一个叫“ 公钥 ”(public key),一个叫“ 私钥 ”(private key)。两个密钥是不同的,“ 不对称 ”,公钥可以公开给任何人使用,而私钥必须严格保密.
公钥和私钥有个特别的“单向”性,虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。 这个逻辑很重要,我们后面还会接触到。要记住噢~ 。
非对称加密可以解决“密钥交换”的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了, 密文只能由私钥持有者才能解密 。而黑客因为没有私钥,所以就无法破解密文.
非对称加密算法的设计要比对称算法难得多,在 TLS 里只有很少的几种,比如 DH、DSA、 RSA 、ECC 等.
RSA 可能是其中最著名的一个,几乎可以说是非对称加密的代名词,它的安全性基于“整数分解”的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的.
10 年前 RSA 密钥的推荐长度是 1024,但随着计算机运算能力的提高,现在 1024 已经不安全,普遍认为至少要 2048 位.
ECC (Elliptic Curve Cryptography)是非对称加密里的“后起之秀”,它基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换, ECDSA 用于数字签名.
比起 RSA, ECC 在安全强度和性能上都有明显的优势 。160 位的 ECC 相当于 1024 位的 RSA,而 224 位的 ECC 则相当于 2048 位的 RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力.
我们要记住RSA、ECC这两个非对称加密算法。很重要.
那~我们直接用非对称加密不就完美了么?也不行,虽然非对称加密没有”密钥交换“的问题,但因为它们都是基于复杂的数学难题,运算速度很慢,即使是 ECC 也要比 AES 差上好几个数量级。如果仅用非对称加密,虽然保证了安全,但通信速度有如乌龟、蜗牛,实用性就变成了零.
那怎么办呢?开动脑筋想一想?
我们可以把对称加密和非对称加密结合起来,两者互相取长补短,即能高效地加密解密,又能安全地密钥交换.
这就是现在 TLS 里使用的混合加密方式 :
在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE,首先解决密钥交换的问题.
然后用随机数产生对称算法使用的“ 会话密钥 ”(session key),再用公钥加密。因为会话密钥很短,通常只有 16 字节或 32 字节,所以慢一点也无所谓。对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密.
这样混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾,完美地实现了机密性.
到目前为止还没完,我们还需要解决其它三个特性的问题才可以。万里长征的第一步要走稳.
上一小节,我们通过学习对称加密和非对称加密的混合加密方式,了解了TLS是如何实现通信的机密性的,但是只有机密性还远远不够.
虽然黑客拿不到会话密钥,无法破解密文,但是可以通过窃听足够多的密文,再尝试修改、重组后发给网站。因为没有完整性保证,服务器只能“照单全收”,然后他就可以通过服务器的响应获取进一步的线索,最终就会破解出明文.
另外,黑客也可以 伪造身份发布公钥 。如果你拿到了假的公钥,混合加密就完全失效了。你以为自己是在和“某宝”通信,实际上网线的另一端却是黑客,银行卡号、密码等敏感信息就在“安全”的通信过程中被窃取了.
那么我们接下来要学习的就是,如何保证会话的完整性,让黑客修改后的报文被服务器拒绝.
实现完整性的手段主要是 摘要算法 (Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function).
你可以把摘要算法理解成一种单向的压缩算法,它能够把任意长度的数据压缩成固定长度、且独一无二的”摘要“字符串,就好像是给数据加上了一个”指纹“。摘要算法只有算法,没有密钥,也无法解密,所以也无法逆推出原文.
摘要算法实际上是把数据从一个大空间,映射到了一个小空间,所以就存在冲突(也叫做碰撞)的可能性,就如同现实中的指纹一样,可能会有两份不同的原文对应相同的摘要。好的摘要算法必须能够“抵抗冲突”,让这种可能性尽量地小.
你一定在日常工作中听过、或者用过 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。但这两个算法的安全强度比较低,不够安全,在 TLS 里已经被禁止使用了。目前 TLS 推荐使用的是 SHA-1 的后继者:SHA-2.
SHA-2 实际上是一系列摘要算法的统称,总共有 6 种,常用的有 SHA224、SHA256、SHA384,分别能够生成 28 字节、32 字节、48 字节的摘要.
摘要算法保证了”数字摘要“和原文是等价的。所以,我们只需要在原文后附上它的摘要,就能够保证数据的完整性.
服务器通过计算源数据的摘要,然后和传过来的摘要比对一下,就可以知道是否是完整的未被修改的数据。如果黑客在中间哪怕改动了一个标点符号,摘要也会完全不同,网站计算比对就会发现消息被窜改,是不可信的.
不过摘要算法没有机密性,如果明文传输,那么黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性.
所以,真正的完整性必须要建立在机密性之上,在混合加密系统里用会话密钥加密消息和摘要,这样黑客无法得知明文,也就没有办法动手脚了。这有个术语,叫 哈希消息认证码 (HMAC).
加密算法结合摘要算法,可以说数据在通信” 过程 “中是比较安全的了。但是只是过程中的安全,还不行,我们还要关注通信的两个端点.
黑客可以伪装成网站来窃取信息。但是反过来,黑客还可以伪装成”你“,向网站发送支付、转账信息,网站没有办法确认你是谁,钱就这么被偷走了.
那,在现实生活中,我们通常通过签名、盖章、加身份证号,来在合同上确认你是谁,确认这份文件确实是你签署的,可以负法律责任了.
那,我们回忆一下,我再限定一下、缩小一下范围,我们在第一小节学习的内容中,有啥是可以确认你是谁的呢?
没错,这个东西就是非对称加密里的“ 私钥 ”,使用私钥再加上摘要算法,就能够实现“ 数字签名 ”,同时实现“身份认证”和“不可否认”.
数字签名的原理其实很简单,就是把公钥私钥的用法反过来,之前是公钥加密、私钥解密,现在是私钥加密、公钥解密.
但是又因为非对称加密效率太低,所以 私钥只加密原文的摘要 ,这样运算量就小的多,而且得到的数字签名也很小,方便保管和传输.
签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的.
刚才的这两个行为也有专用术语,叫做“ 签名 ”和“ 验签 ”.
只要你和网站互相交换公钥,就可以用“签名”和“验签”来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份.
到现在哈,其实我们就解决了所有的问题。机密性通过对称加密和非对称加密的混合加密来解决,完整性就是数字摘要,身份认证和不可否认则是通过数字签名(其实就是”反过来了“,能理解不?)来解决.
但是~还没完~ 。
现在看起来很美好了,但是还有个问题,就是”我“可以发布公钥,那么这个我就可能不是”我“,而是黑客怎么办?黑客可以伪造公钥,换句话说,就是我怎么确定你发布的公钥是”你“发布的,或者是服务器发布的呢?
嗯……这样的问题就叫做” 公钥的信任 “问题.
那,我给这个公钥再用私钥加密一下呢?得……那又会陷入无尽的循环中,所以,此时就必须引入外力来解决了,找一个公认得可信得第三方,让它作为” 信任的起点,递归的终点 “,构建起公钥的信任链.
我们要引入的这个第三方,就是 CA(Certificate Authority,证书认证机构) ,它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的.
CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate).
知名的 CA 全世界就那么几家,比如 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它们签发的证书分 DV、OV、EV 三种,区别在于可信程度.
DV 是最低的,只是域名级别的可信,背后是谁不知道。EV 是最高的,经过了法律和审计的严格核查,可以证明网站拥有者的身份(在浏览器地址栏会显示出公司的名字,例如 Apple、GitHub 的网站).
那,信任链到头了,就到根了,那根怎么证明自己呢?
这还是信任链的问题。小一点的 CA 可以让大 CA 签名认证,但链条的最后,也就是 Root CA,就只能自己证明自己了,这个就叫“ 自签名证书 ”(Self-Signed Certificate)或者“ 根证书 ”(Root Certificate)。你必须相信,否则整个证书信任链就走不下去了.
有了这个证书体系,操作系统和浏览器都内置了各大 CA 的根证书,上网的时候只要服务器发过来它的证书,就可以验证证书里的签名,顺着证书链(Certificate Chain)一层层地验证,直到找到根证书,就能够确定证书是可信的,从而里面的公钥也是可信的.
聊了这么多,终于确保了信息传输的安全,但是,也不是完美的。由于根证书是自证明式的,所以如果CA出了问题,被黑客攻陷,或者失误,或者被欺骗,虽然此时发布的证书是真的,但是它所代表的网站却是假的.
这些情况其实都实际发生过。所以,我们还需要给证书体系打上一些补丁.
针对证书欺骗问题,开发出了CRL(证书吊销列表)和OCSP(在线证书状态协议),及时废止有问题的证书.
对于被攻陷的情况,因为涉及的证书太多,,就只能操作系统或者浏览器从根上“下狠手”了,撤销对 CA 的信任,列入“黑名单”,这样它颁发的所有证书就都会被认为是不安全的.
这篇文章很重要,特别重要。大家一定要好好学习。并且这篇文章内容很多,但是总结起来其实可以概括为两句话.
一个是, 信息传输的安全需要具备四大特性,机密性、完整性、身份认证和不可否认 .
一个是, 安全的终点是自证明的第三方 .
其它的部分,其实都是TLS针对四大特性的具体实现了.
本系列就快结束了~~~大概还有两三篇的内容。坚持~~不一定会胜利,但是不坚持,肯定会失败。共勉吧~ 。
哦对,其实这篇文章是抄的~ 。
最后此篇关于真正“搞”懂HTTPS协议16之安全的实现的文章就讲到这里了,如果你想了解更多关于真正“搞”懂HTTPS协议16之安全的实现的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!