这些东西经常会被用到,但需要真正理解才能正确使用
相关词:MD5、SHA1、 RSA、DSA、AES、BASE64、encoded URL、Unicode、UTF一8、GBK、IS0一8859一1.....
密码学
- 起源:古代战争--古典密码学
- 移位式加密--密码棒
- 长这样
- 密码棒包含了两个核心元素
- 加密算法:缠绕木棒后书写
- 密钥:木棒的尺寸规格
- 长这样
- 替换式加密
- 加密算法:替换文字
- 秘钥:码表
现代密码学
不止可以用于文字内容,还可以用于各种二进制数据。
对称加密
- 原理:使用秘钥和加密算法对数据进行转换,得到的无意义数据即为密文;使用密钥和解密算法对密文进行逆向转换,得到原数据
- 工作模型
-
- 经典算法:DES(56位,因为秘钥太短已被弃用),AES(128,192,256位)
非对称加密
原理:
使用公钥对数据进行加密得到密文;使用私钥对数据进行解密得到原数据。
工作模型
对称加密缺点:中间人攻击
非对称加密,即便中间节点截获了加密秘钥,也无法破解密文
- 加密密文对应的就是公钥↓↓↓,解密秘文对应着私钥↓↓↓
延伸用途: 数字签名
- 公钥和私钥可以互相解密
签名与验证
签名过程
↓
加密+签名
经典算法:RSA,DSA
- RSA 可以用来加密也可以用来签名
- DSA 只能用来签名,签名验证的时候速度更快,如比特币椭圆曲线算法采用的就是DSA
优缺点
- 优点:在不安全的网络上传输秘钥
- 缺点:计算复杂,性能比对称加密差很多
密码学秘钥和登录密码
秘钥(key):
- 场景:用于加密和解密
- 目的:保证数据被盗时不会被人读懂内容
- 焦点:数据
登录密码(password):
- 场景:用户进入网站或游戏前的身份验证
- 目的:数据提供方或应用服务方对账户拥有者数据的保护,保证【你是你】的时候才提供权限
- 焦点:身份/通行码
Base64
将==二进制数据==转换成==由64个字符组成的字符串的编码算法==
(64个字符串 A-Za-z0-9+/)
二进制数据
- 实质上:任何的计算机数据
- 狭义上:非文本数据
用途
- 让元数据具有字符串所具有的特性,可以放在URL中传输、可以保存到文本文件、可以通过普通的聊天软件进行文本传输
- 把原本人眼可以读懂的字符串变成读不懂的字符串,降低偷窥风险
Base64加密传输图片,可以更安全更高效,真的么
不会
- 加密算法是公开的,所以不会更安全
- 每次加密体积增大三分之一,所以也不会更高效
变种
Base58
- 在Base64基础上去掉了大写的O和0(因为它们长得很像),大写的I和小写的l,+和/
- 用于比特币存储地址
-
O和0,大写的I和小写的l防止手抄地址看错写错
-
+和/,为了计算机打字方便,复制等
-
URL encoding
- 将 URL 中的保留字符使用百分号%"进行编码
- 目的:消除歧义,避免解析错误
- hencoder.com/user/?name=…
- ↓
- hencoder.com/user/?name=…
如下,在浏览器地址栏中输入地址,然后粘贴到其他文本编辑器中,会被转义
压缩和解压缩
压缩
把数据换一种方式来存储,以减小存储空间
解压缩
把压缩后的数据还原成原先的形式,以便使用
常见压缩算法
- DEFLATE(zip的压缩算法)
- JPEG
- MP3
如:文本压缩
//原文
aaaaaaaaaaaaaaabbbbbb
//算法压缩
//使用dsh算法压缩,压缩之后变小
dsh:a:15;b:6
//原文
ababababababababab
//使用压缩算反,压缩之后变大了
a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1;a:1;b:1
图片压缩:
//原图
width=100;height=100;ff0000ff0000ff0000...(10000个红色像素点)
//算法压缩
dshImg:type=jpeg;width=100;height=100;data=[0,0-99,99]:ff0000
压缩属于编码么?
属于,符合能够编过去编回来的特点
- ==编码==这个词并没有官方的定义或者标准;
- 通常我们所说的编码指的是 使用固定的规则或算法把数据从A格式转换成B格式并且能转换回来而且还不会丢失信息,如Base64
媒体数据的编码
什么是图片、音频、视频的编解码?
- 图片的编码:把图像数据写成JPG、PNG等文件的编码格式。
- 图片的解码:把JPG、PNG等文件中的数据解析成标准的图像数据。
- 音频、视频的编解码
有损压缩/无损压缩
- 感官相关的东西,如图片音视频,压缩之后仍可以使用但影响体验的,可以使用有损压缩
- 有损压缩无法恢复,不属于编码
*序列化
- 序列化: 把数据对象(一般是内存中的,例如JVM 中的对象)转换成字节序列的过程
- 反序列化: 把字节序列重新转换成内存中的对象
目的
让内存中的对象可以被存储和传输
序列化是编码么
严格意义上讲,序列化不是编码
*Hash
定义:把任意数据转换成指定大小范围(通常很小)的数据
作用
摘要、数字指纹
经典算法
MD5,SHA1,SHA256等
- 好的哈希算法应该避免哈希碰撞
- 如下 haha和hehe的哈希值都是4, 产生了哈希碰撞
public int dshHash(String source){ return source.length(); } dshHash("moneyiloveu!") = 12; dshHash("haha") = 4; dshHash("hehe") = 4;
- 如下 haha和hehe的哈希值都是4, 产生了哈希碰撞
- 同理:好的哈希算法应该能够防破解,及不能通过哈希值找到源数据
实际用途
- 数据完整性验证
- 身份的快速匹配
- 快速查找:hashCode()和HashMap
- 重写equals也要重写hashCode:
- 例如hashMap初步判断相等用的是hashCode,因为hashCode计算速度很快,这样就可以简单快速判断相等;
- 如果hashCode相等,就会用equals判断相等性
- 使hashSet等容器效率更高
- 通常情况下:如果equals为true那么hashcode是一定相等的
- 如果重写了equals而没有重写hashcode,hashmap会认为这是两个不相等的对象,这样就会导致bug的产生
public class Example{ String name; int age; @Override public boolean equals(Object o){ return age == o.age && name.equals(o.name); } @Override public int hashCode() { return age*10000+name.length(); } } - 重写equals也要重写hashCode:
- 隐私保护
用户注册输入 name:willA 用户注册输入 password:123456 -> 服务端SHA1(123456) = qw$%^1 -> 存储在数据库 //服务端并没有存储明文密码,所以一般只提供找回密码功能,而不会像十多年前那样提供密码找回功能 用户登录输入 password:123456 -> 服务端SHA1(123456) == qw$%^1 -> 是willA,登录成功- 彩虹表:密码和哈希值做映射的表叫做彩虹表,一般常用的哈希值可以通过彩虹表查询到原密码,所以很多网站会加点盐
SHA1 (111111) == ksjlkj SHA1 (123456) == awefid SHA1 (888888) == mcv82k- 加盐
123456 -> SHA1(123456abc) = iouhjy
Hash是编码么?
不是
hash是完全不可逆的,无法逆向转换,因为信息损耗很大
Hash是加密么?据说MD5是[不可逆加密]?
不是
- 很遗憾,百度百科是错的
- 加密是可以还原的,MD5不可以还原
签名与验证(完整版)
*字符集
一个由整数向现实世界中的文字符号的 Map
分支
- ASCII: 128 个字符,1字节
- IS0-8859-1:对ASCII进行扩充,1字节
- Unicode: 13 万个字符,多字节
- UTF-8 : Unicode 的编码分支
- UTF-16: Unicode 的编码分支
- GBK/GB2312/GB18030: 中国自研标准,多字节,字符集