再网络传递数据的时候,为了防止数据被篡改,我们会选择对数据进行加密,数据加密分为对称加密和非对称加密。其中RSA和AES,TLS等加密算法是比较常用的。
对称加密
对称加密是指加密和解密使用相同的密钥的加密方法。其基本流程包括以下步骤:
1.密钥生成:
双方协商生成一个共享密钥或由一方生成密钥并安全地传输给另一方。
2.加密:
使用共享密钥对原始数据进行加密,得到加密后的数据。
3.传输:
将加密后的数据传输给另一方。
4.解密:
接收方使用相同的共享密钥对加密数据进行解密,得到原始数据。
非对称加密
非对称加密是指加密和解密使用不同的密钥的加密方法,通常称为公钥和私钥。其基本流程包括以下步骤:
1.密钥对生成:
生成一对密钥,一个是公钥,另一个是私钥。公钥可以公开,而私钥需要保密。
2.公钥分发:
将公钥发送给需要加密数据的一方。
3.加密:
使用公钥对原始数据进行加密,得到加密后的数据。
4.传输:
将加密后的数据传输给另一方。
5.解密:
接收方使用私钥对加密数据进行解密,得到原始数据。
结合使用:
在实际应用中,对称加密和非对称加密通常会结合使用以达到安全和效率的平衡。例如:
-
使用非对称加密交换对称密钥。 -
使用对称密钥进行数据加密和解密。
什么是数字签名
再上面我们了解了RSA对称加密,那么当我们进行数据交换的时候,如下:
假设有AB两个人,假设前面他们已经交换完毕了公钥。
那么此时当A使用B的公钥加密原始数据然后发送数据给B的时候,它可以再数据的后面再携带上一个原始数据hash计算之后得到的hash值,然后用自己的私钥进行加密。
A将数据发送到B之后,由于数据使用的是B的公钥加密,B可以用私钥解密之后,得到A发送消息的原本内容,然后,B可以使用A的公钥对额外的数字签名进行校验,因为它假设这个数据是A发送的,那么用A的公钥就应该可以解密成功,所以如果数据解密成功之后与A发送的原始消息经过一样的Hash运算之后相等,那么说明没有被篡改,而如果不一致,那么就说明被篡改了。因为第三方是不知道A的私钥信息的,所以他是用自己的私钥去加密,得到的hash会与A进行hash之后的值不同,从而判断数据被篡改了。
HTTPS与CA
https其实不是一个单独的协议,而是数据传输的时候使用TLS/SSL进行了加密而已。而TLS就是一个非常典型的非对称加密,其兼顾了AES和RSA的安全性和速度。
上面我们已经聊完了一个加密数据的交换过程,那么如果有些人就是伪造了一些域名让你去访问怎么办呢?
HTTPS (HTTP Secure) 是一个安全的 HTTP 通道,它通过 SSL/TLS 协议来保证数据的安全传输。在 HTTPS 请求的过程中,证书颁发机构 (CA, Certificate Authority) 扮演了重要的角色。以下是 CA 在保证 HTTPS 请求过程中数据安全交换的方式:
证书颁发:
-
CA 为服务器颁发一个数字证书。这个证书包含了服务器的公钥和一些识别服务器身份的信息。 -
数字证书是由 CA 签名的,以验证证书的真实性和完整性。
建立安全连接:
-
当客户端第一次连接到服务器时,服务器会发送其数字证书给客户端。 -
客户端会验证数字证书的合法性,比如检查证书是否由一个受信任的 CA 签名,检查证书是否在有效期内等。 -
一旦证书验证通过,客户端就能确认它是与正确的服务器进行通信,而不是被中间人攻击。
密钥交换:
-
客户端和服务器会使用 SSL/TLS 协议中的密钥交换机制来协商一个会话密钥(通常是一个对称密钥)。 -
一种常见的方法是客户端生成一个随机的对称密钥,然后用服务器的公钥加密它,再发送给服务器。服务器用自己的私钥解密得到对称密钥。
数据加密和传输:
-
一旦会话密钥被协商好,客户端和服务器就会用这个密钥来加密和解密传输的数据。 -
这样,即使数据在传输过程中被截获,攻击者也无法解读数据的内容,因为他们没有会话密钥。
完整性校验:
-
SSL/TLS 协议还提供了数据完整性校验。它会为传输的数据生成一个 MAC (Message Authentication Code),以确保数据在传输过程中没有被篡改。
其实前面的第一和第二随机数都是正常传输,预主密钥的得到就是使用RSA了,此时只有客户端和服务端知道预主密钥,之后,对第一和第二随机数使用预主密钥的加密,就可以得到会话密钥,此时加密交互完成。
并且会话密钥只应用在当前会话,每个会话都会新生成一个,所以安全性大大增加。
只有前面的得到预主密钥的过程用RSA,其他地方都是AES,因为,非对称实在太慢了。
Gateway网关的过滤器链
我们知道,我们可以再Gateway网关中自定义过滤器,并且实现Ordered接口来对过滤器的执行顺序进行排序。如下图我实现了三个自定义的全局过滤器。
并且,当你实现全局过滤器接口的时候,你必须实现如下方法
packageblossom.star.project.gateway.util;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.MultiValueMap;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.Map;
/***@author张锦标*密码学工具包*/
@Configuration
public class CryptoHelper {
public String decryptUrl(String encryptedUrl, String symmetricKey) throwsException {
SecretKeySpec keySpec = new SecretKeySpec(symmetricKey.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedUrl));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}//解析路径参数并且加密,后判断是否和signature一样
public boolean verifySignature(MultiValueMap<String, String> queryParams, String signature, String symmetricKey) throws
Exception {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, List<String>> entry : queryParams.entrySet()) {
//将签名本身从要验证的数据中排除
if (!"signature".equals(entry.getKey())) {
sb.append(entry.getKey()).append("=").append(String.join(",", entry.getValue())).append("&");
}
}
sb.setLength(sb.length() - 1);
String computedSignature = encryptRequestParam(sb.toString(), symmetricKey);
return computedSignature.equals(signature);
}
public static String encryptRequestParam(String requestParam, String symmetricKey) throwsException {
SecretKeySpec keySpec = new SecretKeySpec(symmetricKey.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encryptedBytes = cipher.doFinal(requestParam.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
}
如果请求的过程中,请求的数据并没有被修改,那么可以正确解析,如下
如何实现URL的动态加密?
动态加密其实在上面就已经说了。
可以发现我们发送的实际请求是下面这个,/encrypt/后面的就是我们约定好的加密参数。
“
http://localhost:8080/v1/product/encrypt/WLB8EDs2LNTsUJpS/aANt0XqZ4MvgpFqN/SwDBVwDbERjBkQw62kfAmfsDW2Bngm
实际再处理过程中会去掉/encrypt,他只是用于标识具体的加密参数位置而已。
来源:juejin.cn/post/7284878428817883196
构建高质量的技术交流社群,欢迎从事编程开发、技术招聘HR进群,也欢迎大家分享自己公司的内推信息,相互帮助,一起进步!
文明发言,以
交流技术、职位内推、行业探讨为主
广告人士勿入,切勿轻信私聊,防止被骗

加我好友,拉你进群

本篇文章来源于微信公众号: Java面试题精选
微信扫描下方的二维码阅读本文

Comments NOTHING