前言
我们在做程序开发的过程中,经常会遇到一些需求,是需要对某些敏感数据进行安全传输和保密的。比如 用户的登录和注册操作,用户的登录态维护、以及接口签名、敏感数据加密传输等等。那么这篇文章将会首先介绍相关的比较常见的加密算法的概念,其次我会对一些比较大家常见的名词做一下解释,最后我会再讨论一下根据具体场景下的需求的相应解决方案。
本文不会对加密算法的数学原理,以及各个算法的优点缺点做深入的解释。
写作目的
- 了解加密算法相关知识概念和使用流程,加深对密码学的初步印象。
- 提供涉及到数据安全相关需求的解决方案参考,适合新手参考。
- 加深自己对数据加密知识的基础理解
正文
对称加密算法
概念
加密算法的对称和非对称性,其实很好理解。就是加密过程和解密过程都使用的是同一个密钥的算法就叫做对称加密算法。
常见的对称加密算有:AES,DES,3DES等。
优点
- 加密速度快,效率高、计算量小。
缺点
- 加密和解密使用的是同一个密钥,安全性低。
- 密钥数量多,管理难度高。比如服务端要和N个客户端进行安全通信,那么需要管理N对密钥。
非对称加密算法
概念
非对称加密算法指的就是加密和解密的过程使用的是不同的密钥,一般会在使用非对称加密算法的时候,生成一对“密钥对”。包含一个“公钥”和一个“私钥”。公钥是公开给外部使用的,私钥则是信息接收方自己保留。
常见的非对称加密算法有:DH (又称“Diffie–Hellman"算法)、ECC(椭圆曲线加密算法)、RSA。
比如常见的情况就是,客户端要和服务端进行通信,客户端要发送敏感数据给到服务端。服务端会生成密钥对,将私钥自己保留,公钥发放给所有与之通信的客户端。客户端利用公钥将数据加密之后发送给服务端,服务端解密获取明文数据。
优点
- 安全性高,公钥加密的数据,只有私钥才能解密。其他密钥都不行。
- 密钥管理难度大大降低,对比于对称加密算法。通信的一方只需要保管好自己的私钥,就能和任意个数的另一方进行通信。对方只需要拿指定的公钥进行数据加密即可。
缺点
- 加密和解密花费时间相比于对称加密算法来说会长一些,只适合对少量数据进行加密。
可逆加密算法
概念
可逆加密算法指的是,明文数据通过一系列指定的函数加密之后得到密文,也能通过一定的函数将密文还原成明文的算法。
常见的可逆加密算法有:前文所指的对称和非对称大都是可逆的加密算法。毕竟 大部分场景下 我们是需要得到解密之后的明文数据的。
特点
- 可以恢复回明文数据,适用于那些需要得到明文数据的场景。
不可逆加密算法
概念
不可逆加密算法指的是,明文数据经过不可逆加密算法的加密之后,得到的密文数据很难甚至无法恢复回原来的明文数据。
举个简单的例子,假设一个明文数据为任意的一个数字278,我们的加密算法为将此数字乘以698758。得到的结果就是密文数据,那么正向的乘法很容易计算,但是逆向需要将乘法的结果因式分解回原来的数字就没那么容易了。特别是大素数的因式分解。有的不可逆加密算法就是参考类似的这样的数学原理,找到一种正向容易反向难得的算法过程来实现不可逆加密算法。
常见的不可逆加密算法有:MD5、SHA系列算法(SHA128,SHA256,SHA512)、HMAC系列算法(HMAC-SHA256,HMAC-SHA512)。
优点
- 加密密文不可逆,无法还原或者很难还原明文数据
- 压缩性,任意长度的数据加密之后都是固定的
- 抗修改性,对原数据的微小改动,都会使得加密后的数据不一致
- 抗碰撞性,想要找到两个不一样的明文加密得到同样的密文数据很难。
缺点
- 比较明显的缺点就是,不可逆。无法恢复成明文数据。只适用于数字签名,身份验证相关的场景
常见网络安全相关名词解释
消息摘要
消息摘要是在数字签名中经常使用的一个功能,它的主要实现是使用一个哈希单向散列函数将原文进行处理得到一个固定长度的字符串,我们称这个字符串就是原文的”消息摘要“。也可以叫做”数字指纹“。利用了哈希单向散列函数的压缩性和康修改性。比如我们经常对文件的上传和下载进行MD5哈希函数处理,使用一个MD5值用于鉴别当前文件是否有被篡改,也可以用于判断文件内容是否重复。比如判断是否文件重复上传,以及”秒传“等功能的实现也是借助MD5来判断服务器中是否存储有一样的文件内容。
数字签名
数字签名(又称公钥数字签名)是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术来实现的,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。数字签名是非对称密钥加密技术与数字摘要技术的应用(来自百度百科的词条解释)
常见的逻辑是:信息的发送者,先使用<u>消息摘要技术</u>对信息进行压缩,生成一个信息摘要。然后采用<u>私钥</u>对消息摘要进行加密。加密后的数据就叫做”<u>数字签名</u>“。然后发送者将”<u>数字签名</u>“和原文信息一起发送给接收方,接收方收到信息后,利用<u>公钥</u>对数字签名进行解密,得到发送过来的消息摘要。再利用同样的消息摘要技术对原文进行压缩得到一个接收方自己生成的消息摘要,然后和发送方发送的那份进行对比。如果发现数据不一致,则证明信息内容被篡改。如果一致则证明信息没有被篡改,如果能够正常解密则证明消息确实由发送方发送,否则认为是第三方伪造发送动作。
数字证书
数字证书主要的作用就是解决数字签名过程中存在的某些不安全情况,比如验证方无法判断公钥是否是对方的公钥,或者存储的公钥被替换成欺骗方的公钥等。而数字证书就是通过一个受信的第三方机构进行公钥的颁发,申请人可以向CA机构申请一个数字证书,将自己的公钥已经个人信息注册到CA证书机构。CA证书机构进行各个申请人的公钥和相关信息进行管理,通过机构的私钥对申请人的公钥和信息进行加密得到一个”数字证书“。然后当通信双方进行通信的时候,发送方将发送三个东西,一个是信息原文,一个是数字签名,一个是数字证书。接收方拿到CA机构的公钥(一般已经内置于浏览器中)对数字证书进行解密,得到公钥和公钥发布方的相关信息。然后使用公钥对数字签名进行解密得到消息摘要,最后进行判断。这里我们就可以对这个公钥进行充分的信任,毕竟是可信机构颁发的数字证书。并且经过私钥加密,攻击者无法获取信息和修改。
CA
CA就是CA证书的颁布机构,就是一个数字证书管理中心,可以这么理解。
中间人攻击
中间人攻击(Man-in-the-MiddleAttack,简称“MITM攻击”)是一种“间接”的入侵攻击,这种攻击模式是通过各种技术手段将受入侵者控制的一台计算机虚拟放置在网络连接中的两台通信计算机之间,这台计算机就称为“中间人”。(来自百度百科词条)
比如有:会话劫持,DNS欺骗,伪造SSL证书等。
会话劫持的原理指的是,攻击者通过分析客户端和服务端直接通信的网络数据包,比如从HTTP连接的cookie中拿到双方通信的会话,然后使用此会话进行登录目标网站完成操作。
DNS欺骗指的是,攻击者对客户端本地的DNS域名解析进行污染。修改DNS解析域名的映射到攻击者本机,这样当客户端进行域名访问的时候就会将数据转发到攻击者的IP上去。由攻击者进行控制和转发相应信息。
伪造SSL证书也是类似的原理,通过伪造一对RSA的公私钥对,然后与客户端和服务端进行双向SSL认证。变成双方数据通信的中间人。
JWT
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object (来自jwt.io官网对JWT的介绍)
简单来说就是JSON格式的Token字符串。里面包含三个部分。分别是:header、payload、signature。
header主要描述的内容是算法类型和token格式。
For example:
{
"alg": "HS256",
"typ": "JWT"
}
payload主要描述的内容是具体的传输数据,以一个JSON对象的形式出现。里面也可以有自定义的数据字段以及一些官方标准提供的数据字段。
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
最后的signature签名则是通过之前约定的加密算法,然后对前两个部分进行base64URLEncode,部分之间通过“点号”拼接得到。
For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
常见数据安全场景
用户进行系统的注册、登录、资源访问
我们先说一下注册的场景,注册的时候主要需要防范的出现的情况是,用户注册的用户名密码等敏感数据明文被攻击者获取,然后攻击者可以去自由登录进行访问系统资源。
那么我们可以采用非对称加密的方式来加密明文,然后服务端进行密文的解密得到数据。攻击者没有私钥,无法解密得到明文信息。
还有的情况就是,攻击者能够截取服务器数据库,获得明文密码。或者明文密码存储在数据库,被内部人员等等偷偷泄露。所以用户的敏感数据一般都是直接密文存储在数据库中的。但是哈希密文也不一定可靠,攻击者可以根据密文进行推测和计算等等的方式去破解哈希,比如字典攻击和暴力攻击,查表法、反向查找法、彩虹表等等。
比如MD5哈希的安全性就不可靠
所以我们可以采用相对安全的哈希加密算法SHA256,SHA512等,再搭配随机盐值来降低哈希密码被破解的可能性。
下面是我画的注册用例的时序图
总结
需要解决的问题:用户敏感数据明文被截获、明文密码在数据库被泄露
解决方案:非对称加密算法进行数据传输、长度更长,更安全的哈希加密算法+安全随机盐值对明文密码进行哈希加密
登录场景下需要注意的地方就稍微多一点,因为密文也不安全了。攻击者不需要指定明文,只要截获密文一样可以进行登录操作。
所以我们需要一个临时登录码code,来防止攻击者的重放攻击。临时登录码中涉及可以包含过期时间以及一些自定义的信息,然后每次用户登录的时候不仅要携带常见的登录信息数据,同时还要放上服务端颁发的临时登录码。
这样攻击者每次截获的登录密文都会不一样,及时能够截获有效的登录密文数据,也无法再重放登录请求了。
另外的一个需要考虑的事情就是登录保持,常见的做法是服务端会再用户登录成功会颁布登录态给到用户,一般是存储在cookie中。还有一种就是JWT的方式,通过Header传递登录态信息。会话的安全性也就成了我们要解决和防范的问题,如果攻击者进行了会话劫持,那么就可能使用用户的会话进行系统资源的访问。
主要有几个点可以进行防范,一个是会话ID不可预测,使用随机的比如UUID等,生成会话ID。另一个是设置较短的会话超时时间,减少单个会话的访问有效性。降低系统被攻击的风险,还有一个就是从HTTP协议header中对请求进行更细致的判断和规定,比如UserAgent、Refer等。或者对某些接口做接口签名,防止攻击者随意伪造请求。
下面是我画的登录用例时序图
总结
需要解决的问题:攻击者重放攻击、会话安全性
解决方案:临时登录码、接口签名、减小会话有效期
HTTPS原理和流程
HTTPS也是比较典型的数据传输安全解决方案,具体的流程可以参考这两篇文章,主要讲SSL/TLS协议。
文章最后
软件系统的安全性保护没那么简单,需要很多方方面面的知识和经验,才能做到比较安全的保护。通过这一次的总结学习,大概了解了常见的加密算法的作业和实践。以及具体场景下需要考虑的问题和解决方案,当我再面对同样的需求,和同事们讨论的时候也不至于一窍不通啥也不懂啦。