编码、加密、Hash、序列化和字符集

2021/09/04

了解编码、加密、Hash、序列化和字符集的概念。

编码

编码是信息 (文本或者非文本的二进制文件) 从「一种形式」或者格式转换到「另一种形式」的过程。

编码只是表现形式的转换,并不是一种加密方式。

常见的编码有:

  • Base64编码
  • URL编码(也叫%编码)
  • 压缩/解压缩编码

Base64编码

用途

Base64编码 可以把非文本的二进制文件 (如图片、视频) 转换成字符串。可以用普通表单(只支持传文本)上传图片。

Base64传图片是很老的方法,可以用multipart或者image/jpeg的方式传图片; Base64不是一种加密方式,并不安全; Base64会增大文件体积,并不高效。

URL编码

用途

URLEncodeURLDecode 是问了消除歧义,避免解析错误,把保留字符转换成%编码

比如 https://www.baidu.com/s?wd=编码 会被转换成 https://www.baidu.com/s?wd=%E7%BC%96%E7%A0%81

压缩/解压缩编码

用途

顾名思义,压缩 是减少文件体积,方便传输;解压缩是把压缩后的文件还原成原文件。

常见的压缩文件格式

  • zip:文件压缩,压缩算法是DEFLATE
  • JPEG/PNG:图片压缩
  • MP3:音频压缩
  • MP4:视频压缩

压缩分成「有损压缩」和「无损压缩」,「有损压缩」是不可逆的。

加密

对称加密

对称加密:密钥相同,加密算法和解密算法不同。

常见对称加密算法

  • DES:密钥太短(64位),已经弃用
  • AES:密钥有128位、192位和256位

对称加密的缺点:密钥传输有风险。

非对称加密

非对称加密:密钥不同,加密算法和解密算法相同。

常见非对称加密算法

  • RSA:可以用来加密和签名
  • DSA:只用来签名(速度快)

非对称加密会生成一对密钥:公钥和私钥。其中私钥自己持有,绝对保密;公钥是可以公开出去的。这样就避免了密钥传输风险。

私钥加密的密文,可以用公钥解密;公钥加密的密文,可以用私钥解密;但是公钥和私钥不能替换,因为公钥可以通过私钥计算得到 (椭圆曲线算法)

数字签名和验证

非对称加密会遇到 数据伪造风险 (使用公钥伪造数据),所以产生了 「数据签名-验证」的用法。

  • 签名A私钥对原数据的「Hash」进行加密,得到「密文」,同时把「Hash」和「密文」发给B
  • 验证B公钥对「密文」进行解密,得到的结果和「Hash」对比,如果一致说明确实是用A的私钥加密的,证明发送方确实是A

加密的使用流程

没有一种加密方式是绝对安全的,对称加密和非对称加密也没有优劣之分。需要根据具体场景选择适合的加密方式。

前提说明:

  1. A、B是通信双方,默认A和B所持有的数据是不会泄漏的(这里只分析传输过程中的安全问题);
  2. C是坏人,假设通信过程中的所有数据都会被C所拦截。

对称加密的使用流程

情景1:

1. A和B都有密钥,不需要传输密钥; 2. C只能拦截到密文,无法解密,是安全的。

情景2:

1. A没有密钥,B有密钥,B需要把密钥传给A; 2. C同时拦截到密文和密钥,是不安全的。

非对称加密的使用流程

情景1:只有一对公钥和私钥

**1. B持有自己的私钥,公钥公开给A和C;

  1. A使用B公钥加密后的密文发送给B,B再用B私钥解密;C无法用B公钥解密,安全;
  2. B使用B私钥加密后的密文发送给A,A再用B公钥解密;C也可以用B公钥解密,不安全;**

情景2:有两对公钥和私钥(A和B)

1. AB分别持有自己的私钥,和对方的公钥;C也持有两者的公钥; 2. A使用B公钥加密后的密文发送给B,B再用B私钥解密;C无法用B公钥解密,安全; 3. B使用A公钥加密后的密文发送给A,A再用A私钥解密;C无法用A公钥解密,安全;

如果改成用私钥加密,公钥解密会怎样呢?

用私钥加密,就要用公钥解密,C拥有两个公钥,所以是不安全的。

数字签名和验证

上面采用两对公钥和私钥,并且用公钥加密,私钥解密的方案,还有一个风险,就是C可以用公钥伪造数据发送给A和B。

情景3:使用数字签名和验证

1. 首先,对原数据进行Hash计算,得到原数据的Hash值(体积小,方便传输); . 使用自己的私钥对Hash进行加密(签名),然后把Hash和密文发送给对方; 3. 接受方使用对方的公钥解密,然后和原数据Hash对比,如果一致,说明发送方是拥有私钥的(验证); 4. C没有A和B的私钥,所以无法伪造。

情景4:完整的加密和签名流程

所以非对称加密传输数据,需要: 1. 两对公钥和私钥; 2. 用公钥加密,私钥解密; 3. 用私钥签名,公钥验证。

Hash

用途

Hash 是把任意数据转成指定大小(一般很小)的数据。可以用来作摘要、数字指纹

摘要、数字指纹就好像人的DNA一样,可以用来唯一表示该数据,但是不能逆向还原出原数据。

应用场景
  • 数据完整性验证

对数据Data进行Hash,得到DataHash(很小),接收方接受到Data后再进行一次Hash,得到的结果跟DataHash对比,一致的话可以认为接收到的数据是完整的。

  • 快速查找

HashMap是一个可以用来快速查找的数据结构,通过对比对象的Hash值实现。

Java的Object对象有默认实现的equals()hashCode() 方法,通过hashCode()可以快速判断两个对象是否相等,如果hashCode相等再判断equals()(所以要重写equals()方法也要同时重写hashCode()方法)

常见的Hash算法

  • MD5
  • SHA1
  • SHA256

序列化

  • 序列化:把内存中的对象转换成字节序列(一般是JSON),用于存储或者传输
  • 反序列化:把字节序列(一般是JSON)转换成内存中的对象。

Java 中实现 Serializable 接口,就可以对对象进行序列化。

字符集

字符集 是一个由整数向现实文字符号的映射(Map)。简单来说就是用整数表示文字符号。

  • ASCII 字符集
  • Unicode 字符集
    • UTF-8:Unicode的编码分支
    • UTF-16:Unicode的编码分支
  • GBK 字符集

一个字符集的不同编码分支,指的是同一个字符集的不同表示方式; GBK现在基本退出历史舞台。


公众号:JairusTse的日常

(转载本站文章请注明作者和出处 JairusTse的技术博客

Post Directory