分两篇:
- 第一篇:了解加密加密的基本概念
- 第二篇:实践前后台的加密解密流程
目标
-
了解常规的加密和解密方式
参考:crypto-js 加密用的js
写给大忙人看的JavaSE8 书籍 - 第7章
Java8 Nashorn实现Java调用javascript代码
随笔记:java中调用JavaScript方法(多js文件)
Java和Js之间的调用、java8新特性:ScriptEngineManager
如何写出健壮的代码? 推荐阅读
几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式
签名
从支付宝SDK的支付流程理解什么是公钥和私钥,什么是加密和数字签名Rsa2验签报错【java.security.SignatureException: Signature length not correct】的解决办法
在人人都会爬虫的今天,对于接口的获取,参数的分析都可能会发现接口的漏洞。参数的加密与解密是保障接口安全的一种措施,能够为我们解决很多问题。
接口可能存在的问题
-
过度依赖接口获取的请求参数
对于某些数据,仅通过接口参数来执行某些业务规则,可能会导致后台业务的失效和数据的混乱。
-
无法甄别请求参数的合法性正确性
我们希望接口接收的参数必须是合法的,参数是没有被篡改。
-
接收和响应敏感数据
在接口参数和响应敏感数据,比如手机号,身份证号等等,可能会导致信息的泄露。
通过对参数的加密和解密,以此来解决上述的问题
加密与解密一些概念
参考:MD5在线加密
加密类型
- 对称加密(symmetric),例如:AES、DES等
- 非对称加密(asymmetric),例如:RSA、DSA等
- 摘要加密(digest),例如:MD5、SHA-1、SHA-256、HMAC等
-
对称加密
指加密和解密使用同一个密钥。所以在使用对称加密时,需要先生成一个密钥。
对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信的安全性至关重要。
-
非对称加密
加密和解密使用两套钥匙,一个是公钥,一个是私钥,使用之前,需要生成公钥和私钥。
对于非对称加密,最常用的就是RSA和DSA,非对称加密有公钥和私钥两个概念,私钥自己拥有,不能给别人,公钥公开。根据应用的不同,我们可以选择使用不同的密钥加密:
- 签名:使用私钥加密,公钥解密。用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改,但是不用来保证内容不被他人获得。
- 加密:用公钥加密,私钥解密。用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得。
-
摘要加密
摘要算法是一种能产生特殊输出格式的算法,这种算法的特点是:无论用户输入什么长度的原始数据,经过计算后输出的密文都是固定长度的,这种算法的原理是根据一定的运算规则对原数据进行某种形式的提取,这种提取就是摘要,被摘要的数据内容与原数据有密切联系,只要原数据稍有改变,输出的“摘要”便完全不同,因此,基于这种原理的算法便能对数据完整性提供较为健全的保障。
但是,由于输出的密文是提取原数据经过处理的定长值,所以它已经不能还原为原数据,即消息摘要算法是不可逆的,理论上无法通过反向运算取得原数据内容,因此它通常只能被用来做数据完整性验证。
其他概念
参考:签名 支付宝的签名步骤
从支付宝SDK的支付流程理解什么是公钥和私钥,什么是加密和数字签名
-
数字签名
参见百度百科
数字签名(又称公钥数字签名)是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术来实现的,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。数字签名是非对称密钥加密技术与数字摘要技术的应用。 [1]
数字签名的主要目的有两个:
一、用来互相验证接收方和发送方的身份;
二、在验证身份的基础上再验证一下传递的数据是否被篡改过。
因此使用数字签名可以用来达到数据的明文传输。
签名主要包含两个过程:摘要和非对称加密,首先对需要签名的数据做摘要(类似于常见的 MD5)后得到摘要结果,然后通过签名者的私钥对摘要结果进行非对称加密即可得到签名结果。
-
非对称加密的 签名 和 加密
首先,明确 公钥 允许每个人都知道 私钥自己拥有,不能给别人
那这种特性,就可以衍生出两种方式
公钥加密,私钥解密
公钥加密数据,能保证只有私钥身份的,才能解密数据,其他人无法获得真实数据。但是不能保证这个数据不被修改,因为大家都知道公钥,都可以对数据进行加密。
私钥加密,公钥解密
私钥加密,能保证只有私钥身份的,才能加密数据,可以防止真实数据被篡改。可以让公钥身份来验私钥所有者的身份,不是由私钥身份加密的数据,公钥都解密不成功。但是不能保证内容不被其他人获取,只要有公钥身份的人,都可以解密数据。
前端的加密
前端加密一般都是通过js将参数进行加密处理,再请求后台接口。
很多人认为前端加密是没有意义的,因为前端写的js 都是公共透明的,就算加密了参数也无大用。加密过程和加密后的密文,都可以拿到。直接使用密文调用接口一样可以。
我认为,前端加密参数的意义在于:
(1)防止中间人获取真实数据,防止撞库,保护用户的信息安全。使用非对称加密方式,使用公钥加密,能保证数据在传输过程中,中间人无法获得真实数据。所有安全措施的目的不都是提高破解成本,而是要对用户信息负责。
(2)增加模拟调用接口的难度,通过js加密,模糊请求参数,可能某些攻击者在构造数据过程中,被加密过程的繁杂和模糊参数困扰,不愿意再对其分析。当攻击者模拟未被处理的数据,会被接口直接拒绝。一定程度上保护接口安全。攻击和防御本身就是一种博弈,通过简单的措施,提供攻击的成本,还是必要的。
后端的加密和解密
-
HTTPS 协议
简单的理解Https协议,就是http协议+ssl(安全套接层)组成的。
前端发送请求后,这个请求携带的请求信息,会通过各种路由器,交换机进行代理转发,最终被我们的服务器所接收到。仅仅通过HTTP协议无法保证该请求是否遭遇劫持、监听、篡改,因为HTTP是明文传输的。期间要保证请求的安全,比如请求信息不会被篡改,请求信息不回被中间人获取,就需要使用HTTPS协议。
我们都知道HTTPS是安全的HTTP,那么HTTPS是如何保证通信过程的安全的呢?
如果服务器给客户端的消息是密文的,只有服务器和客户端才能读懂,就可以保证数据的保密性。同时,在交换数据之前,验证一下对方的合法身份,就可以保证通信双方的安全。(和我们平时开发中RSA加签验签,加密解密的过程比较像)。HTTPS就是利用了类似的原理来保证通信的安全性。
所以HTTPS保证安全通信的步骤主要分为两步:
- 通信前验证对方的合法身份;
- 将通信的报文加密,通过密文进行通信。
如果希望保护你的请求,请使用HTTPS
后端对于参数的加密,通过包含在几个场景下:
- 服务间接口的调用(可以考虑使用对称加密算法,因为密钥不会被泄露)
- 响应数据的加密
后端对于参数的解密:
- 解密接收的参数值
- 验证签名
前后端加密的工具
前端加密js:
-
crypto-js 是一个纯 javascript 写的加密算法类库 ,可以非常方便地在 javascript 进行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。 但是不包含 RSA 非对称加密算法。
-
也可以查看这个网址:http://travistidwell.com/jsencrypt/
专注于RSA加密
后端加密java工具类:
-
hutool
https://www.hutool.cn/docs/#/crypto/%E6%A6%82%E8%BF%B0
hutool-crypto针对这三种加密类型分别封装,并提供常用的大部分加密算法。
-
支付宝的RSA加密
可以复制一下,里面提供的RSA加密解密方法