编码、加密

676 阅读21分钟

1、密码学

起源:古代战争

  • 古代打仗的时候,会要信使骑个马送信。他们经常会担心信使被抓。

移位式加密:密码棒

  • 比较早的一种加密方式 在这里插入图片描述

  • 一个布条缠在密码棒上面,两边都有同一规格的密码棒

替换式加密

在这里插入图片描述

  • 也可以用码表

2.现代密码学

  • 不止可以用于文字内容,还可以用于各种二进制数据。

对称加密:

  • 跟替换式加密很像

原理:

  • 使用密钥和加密算法对数据进行转换,得到的无意义数据即为密文;
  • 使用密钥和解密算法对密文进行逆向转换,得到原数据。

过程:

  • 原数据,用加密算法以及密钥,把他改成了看不懂的密文,

  • 这个时候对方拿到密文,并且他有密钥,其他人都没有。然后他就可以去解密,

  • 他使用解密算法配合上密钥,他就能解密,得到原数据。 在这里插入图片描述

  • 这个对计算机很有用,为什么?

    • 因为我们通讯的时候,我们的网络是完全不可信的。
    • 从我家到你家这一路上,可能有非常非常多的中间节点,他们想拿我们的中间的数据轻而易举。为什么?
      • 我们网络传数据,比如说我给你发一条信息,不是这个信息在一条路上走,而是喊话式的,都是辐射式的。
  • 他跟传统的替换式加密有什么不同呢?

    • 他可以加密二进制文件

经典算法:

  • DES(由于密钥太短而被弃用了)
  • AES

为什么密钥短就被弃用?

  • 因为密钥短就可能会被破解。 什么叫破解呢?什么叫对称加密的密钥的破解呢?
  • 是这样的,我们通讯的破解,我们古代战争写信,我知道你的密码棒是什么规格,我知道你的码表是什么,当我拿到你加密后的那一封密文,我可以给你恢复回来。那么我拿到你这个密文或码表,就破解了。
  • 他的关键是什么呢?你能够拿到一组原文和密文的对,然后你用你准备好的密钥对这个密文解密之后,他真的恢复成原文了,这表示破解成功了。 同样,有破解就有反破解。
  • 反破解的思路非常直,就是我让你破解的方法更加复杂。
  • 最优秀的加密算法就是,他的密钥的破解方式只能是穷举法。
  • 你不可能让别人破解不了,只是成本非常高,比如要一千年,一万年才能破解,那么我认为你这个东西不能破解。

非对称加密:

原理:

  • 使用公钥对数据进行加密得到密文;
  • 使用私钥对数据进行解密得到元数据。

经典算法:

  • RSA(加密解密,签名验证都可以)

  • DSA(专门设计用来签名的,签名和验证的过程特别快,有速度优势,椭圆曲线全称就叫ECDSA) 在这里插入图片描述

  • 怎么做到的呢?

    • 用的是数学知识。我可以简单解释一下,但是我的这个解释是不足以完全说明非对称加密的。因为非对称加密最简单的算法也比较复杂。RSA算法就算一种比较简单的算法了,但是还是比较不好理解。所以我跟你举一个简单例子。这个例子可能会有漏洞,但是你要知道她是什么意思。
      • 比如,我们双方通讯了,
      • 我们规定通讯内容只有十个,0-9,只能发这十个。
      • 比如我现在给你发一个消息110,但是我如果被人截获了那我就完蛋了。所以我要对她做一下转换。
      • 然后我要怎么转?我的算法是什么?我的加密密钥和解密密钥是什么?这个时候就体现出来了他的用处了。
      • 我的加密算法是,对我的每一个字符都做一个加法。而这个加法具体加几,就是我的密钥了。
      • 那么我规定,我的加密密钥是4,我的解密密钥是6,加密:110-->554,发出去。
      • 接下来, 我要解密,我的解密算法还是加,但是加的是6,554-->110,恢复了。
    • 这个例子虽然有漏洞,但是她能解释非对称加密的原理。他是跟溢出有关的,如果不可以溢出的话,非对称加密就没法玩了。你各种溢出,删掉他前面的点,这个是非对称加密很关键的一个点。 在这里插入图片描述
  • 对称加密,不是挺安全的吗?为什么又要非对称加密呢?

    • 有一个很重要的原因,就是你的密钥怎么给对方。
    • 非对称加密他很重要的一个好处。我可以在网上直接把密钥进行传输,没有任何安全隐患。
    • 看一下怎么没有安全隐患。
      • 首先,我把我的加密密钥从a给到b,b也把她的加密密钥从b给到a。
      • 首先我看a和b能不能通讯,比如a要给b发消息,我用b的加密密钥,去加密我的原数据。加密完以后就是密文了,
      • b拿解密密钥解密,就得到原数据。同样,b给a发消息也是这样。
      • c拿到这个密文他肯定看不懂,但是如果他不仅仅拿到密文,他还拿到了我们传输过程中发送的这个两个加密密钥。现在他能看我们的密文吗?
      • 我现在有一个密文,是a发给b的,他用b的加密密钥加密了, 你说c拿哪个密钥来解?都不行。
      • 非对称加密很关键的一个点是,他加密和解密用的不是一个密钥。所以这个时候你拿我的两个加密密钥是没有用的。
      • 解密密钥是要拿在手里不能动的,这个是关键。一定要拿在手里面,谁都不能给,不可能往外发送的。
      • 而加密密钥随便往外公开。事实上你往外公开的这个加密密钥他叫公钥,解密密钥叫私钥 在这里插入图片描述

非对称加密延伸用途:数字签名

公钥能不能解私钥?

  • 首先有一个问题,私钥是可以解公钥的,那么公钥可不可以解私钥呢?是可以的。
  • 但是有一点要注意,公钥和私钥是不能反的。因为很多时候公钥是可以通过私钥被计算出来的,有一种非对称加密算法叫椭圆曲线算法,他是比特币用的一种算法。他的公钥就是依靠私钥算出来的,你拿到私钥就相当于公钥和私钥同时拿在手里。虽然他们在数据转化上有对等关系,但是很多时候你的公钥是可以被人算出来的,所以你公布一个公钥出去没关系,本来就要公开,只要私钥不公开你没发推算出我的私钥。
  • 还有一种情况就是RSA,RSA他的公钥甚至只有一个,你家公钥是这个值,我家公钥也是这个值,也不是公钥完全是一个值,就是公钥的一部分,公钥最关键的那一部分是一样的。好像是65537我记得。所以公钥和私钥是不能对换的。但是他们在加密上是完全一样的。你可以解我,我可以解你。
  • 由于有这么一种特性,我就可以去做签名和验证了。

签名和认证:

  • 现在有一种比较常见的用法就是在网上进行数字签名,进行电子签名。就是我有一个我的密钥。我对我的数据,比如说我声称我欠了小庄一百块钱,我可以手写,我也可以使用电子签名式。他是怎么签名呢?就是使用我的某个密钥,对我写的文章进行加密算法转化之后,别人拿到之后,再用另外的公钥解密,一看,可以置换成原数据,就可以证明这个东西确实是我写的。 在这里插入图片描述

  • 另外,还会有这样一步,附带原数据

  • 你只拿着这个签名数据很不方便,每次看都要用公钥解密以后才能看到原数据。所以一般会把原数据和签名数据一起发送出来。这个时候你看原数据可以看,你要验证这个数据可以用签名数据还原。 在这里插入图片描述

3.Base64

定义

  • 将二进制数据转换成由64个字符组成的字符串的编码算法。(a-z、A-Z、0-9、+、/)
  • 什么是二进制数据?
    • 非文本数据就是二进制数据,广义的,所有的计算机数据都是二进制数据。因为电信号只有1010,计算机数据只有两个位,计算机数据都是二进制数据,不管什么文本文档啊,电影啊,word文档啊,图片这些都是二进制数据。
    • 而其中有一种比较特殊的叫做文本数据,就是纯文字,比如字符串,比如你的一个txt文档里面存的一些文字,这些叫文本数据或者叫字符数据。文本数据之外的,就是我们通常沟通的时候所说的二进制数据,也就是狭义的二进制数据。所以数据就分两种,文本数据和二进制数据。

base64的码表:
在这里插入图片描述

2的6次方是64,base64是6位的

  • 他是怎么转换的呢?
    • 他是将你的数据切一下。我们做数据的时候不是一个字节有8位吗?一位是0或者1,只能二选一,八位是一个字节,但是base64为了能让你的数据变成字符串,他就把你切成了6位放在一起。具体的转化是这样的,Man转化成base64就是TWFu。 在这里插入图片描述

base64转化完以后会把数据量变大的。

  • 怎么让你的数据base转化以后还不增大呢?
    • 那就别用base64,用base256,但是为什么base64被创建出来?就是因为那些常见字符没有256个,如果真有256个那还需要什么base64。base64的目的是什么?他的目的就是把你的二进制数据(狭义的)转化成文本数据,给转化成字符串。

用途:

  • 让原数据具有字符串所具有的特性,如可以放在URL中传输、可以保存到文本文件、可以通过普通聊天软件进行文本传输。(把非字符串转成字符串)
  • 把原本人眼可以读懂的字符串变成读不懂的字符串,降低偷窥风险。

什么时候会需要base64呢?

  • 举一个比较早期的场景,就是邮箱刚被发明,邮箱不能发图片的。但是电脑可以存图片,那么我怎么给你发图片呢?好,我用base64转一下,文件变大了,没关系啊,慢慢传。然后再用base64的解码算法给他解出来。那么我们就通过文本的方式传图片。
  • 再举一个例,假如我们两个造了一个新的聊天软件,但是咱俩技术有限,没法支持图片,传不了图片,怎么办?没关系,把图片转成base64,然后我给你传base64的文本数据,传过去之后你再在本地解一下,解码完就是那个图片了。这个就是什么呢?就是有的时候他有限制,不能这么做,古老的邮箱就是这样,没这个功能,不能传图片,我又想传图片。好,我就用base64转一下。

base64加密传输图片,可以更安全和高效吗?

  • 不是的。安全只能靠加密,base64不是加密;
  • 高效,base64转化后数据变大了,变长了1/3,那还能高效吗?
    • 你不管是存储还是传输,还是读取,他的速度都变慢了,而且还占你带宽,你可能本来传这个东西,这个东西传完以后,传别的东西,可以更早传完,但是由于你这东西被base64转过一遍,完蛋了,你需要延长1/3的传输时间。base64绝对没有什么高效,相反他是低效的。能不base64一定不要base64,而且这个东西有毒,你每次做这个东西他都会变长。

Base58

  • base64有一个变种,base58,他去掉了0和大写o,英文的大写i和小写l,另外还有两个+和/。他用在比特币或者其他虚拟币的地址上面。这个地址有什么特点呢?他可能会被手抄。去掉+和/是为了方便双击复制。

4.URL encoding

  • url地址的编码是base64 的另一个变种

  • url的编码也是base64的,但是他有一点点区别:

    • 将url中的保留字符使用百分号“%”进行编码 举例:将保留字符中的&转化成%26: 在这里插入图片描述
  • 目的:消除歧义,避免错误

  • 还有就是用于中文显示 在这里插入图片描述

显示是有中文的,但是复制下来就没了

https://www.google.com/search?q=%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E7%AE%97%E6%B3%95&oq=%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E7%AE%97%E6%B3%95&aqs=chrome..69i57j0l2.7739j0j7&sourceid=chrome&ie=UTF-8

5.压缩和解压缩

  • 压缩:把数据换一种方式存储,以减小存储空间
  • 解压缩:把压缩后的数据还原成原先的形式,以便使用 常见的压缩算法:
  • DEFLATE(zip用的压缩算法)、
  • JPEG、
  • MP3 压缩属于编码吗?
  • 编码到底是什么?把a格式转化成b格式,同时b格式是可以转回来的,不会损失任何信息,不会增加任何信息。压缩也是属于编码的一种。

6.媒体数据的编解码

  • 媒体数据是什么?

    • 就是图片啊、视频、音频这些东西,他们的编解码是什么呢?
    • 他们的编解码就是把原先的数据转化成可以存储的一种编码格式。比如对于图片就是把图像数据编成文件。
  • 举个栗子,图像怎么做编码呢?

    • 比如我有一个图片,这个图片是64x64的,他是一个纯白的图片。那么我怎么写,怎么保存呢?他在内存里面可能是一个bitmap,当我要把他编码出来,要保存的时候,怎么存?
      • ffffff表示一个白点
      • ffffffffffff......64x6个
      • ffffffffffff......64x6个
      • ffffffffffff......64x6个
      • ......64行
    • 这个就是编码后的图片,但是这样好烦啊,这么大。我们可以压缩,在编码的同时进行压缩,怎么压缩呢?有各种各样的压缩方法。假如我们真的要做压缩的话,DEFLATE算法以及各种其他算法他们本质上是什么呢?
  • 举例:aaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaaabbbbbbbb...bbbbbb

    • 某种粗略压缩后:text:a=100;b=20
    • 上面的图片也可以:
      • image:64*64;
      • ffffff=[0,0]-[63,63]
    • 同样音频视频的压缩也是这样的,上面只是举例,这个压缩并不严谨,优秀的压缩算法永远不会让文件变大,上面这种一旦种类变多,可能压缩完后比文件本体还大。
  • 有损压缩和无损压缩:

    • 可以把她的像素变小一点,也可以把颜色数改少一点,这样压完我的数据就会有损失。

7.序列化

  • 我java内存里面有一个数据,他有几个属性 在这里插入图片描述

  • 这是在内存里面,我需要把这些东西传出来,一个是我们的网络上,另外也可能是我们的手机或者本地存储,但是我们的内存里面是乱乱的,我们怎么存各种格式?我要把他拿出来,成线性的,可以通用解析的一个格式。这就是序列化。

  • 像上面的我可以序列化出来成json格式。如果序列化出来,我可以选择json格式,json只是序列化的一个选项,你可以序列化成json、xml...总之你只要把她转化成可以存储,可以传输,她是一个线性的就可以了。 在这里插入图片描述

  • 序列化:

    • 把数据对象(一般是内存中的,如JVM中的对象)转化成字节序列的过程
  • 反序列化:

    • 把字节序列重新转换成内存中的对象。
  • 目的:就是跟外界通讯

序列化属于编码吗?

  • 序列化严格来说不属于编码,因为序列化他的原型在内存里面,编码是什么a格式变b格式,编码是已经成型的两个东西他的格式转换,但是序列化他的原型就不是格式,是内存里面的一坨。只是严格意义上来说不是编码,其实编码并没有一个严格规定。

8.Hash

定义:

  • 把任意数据转换成指定大小范围的数据(通常很小)
  • 比如我们有两百个同学,我们把每一个学员编一个号,001,003....这个过程就是一个hash过程,而每个人他的编号就是一个hash值。

作用:

  • 用作摘要、数字指纹

  • 比如:

    • 直接用字符串的长度做hash
      • "haha"-->4
      • "pa"-->2
      • 后面是数值就是hash值,这是一种很差劲的hash,因为
      • "hehe"-->4
    • hash他会有身份识别的这种要求,所以hash要求有极小的碰撞率,那么就研究你的hash算法要怎么算,给你的数据可能非常大,也可能非常小。你都需要快速得出结果,并且互相之间不会碰撞。

经典算法:

  • MD5(在防破解方面已经基本被遗弃了,因为他太容易破解了)、
  • SHA1
  • SHA256

实际用途:

数据完整性验证:

  • 比如我们要下一个安装包,那个发布者可能会在下面给你提供一个用于验证的hash值,他会给你指明这是一个sha1值还是一个sha256,还是一个md5,他会跟你说,也有可能会给你提供多个验证的值,这个有什么作用呢?上传者这有一个源文件,他有5个g,他的md5值算完以后是7788, 你下载以后,你这个下载文件可能已经损坏了,可能下载过程中你的下载工具出错了,或者有人修改你的网络了,总之你下完以后,这个东西可能是破坏了的,你对下载后的文件也算一下你的hash值,比如算一下文件的md5,如果也是7788,证明你下载的这个文件是完整的。如果你算完是2567,那么你这个文件下载失败了。
  • hash就像是在你的一堆数据里面抽取特征值一样。如果你多次计算都是这个结果,那么他就可以当成一个指纹一样的存在。

快速查找:

hashCode()和HashMap

  • java中有用到hash的时候,重写equals方法的时候也要重写hashCode方法 在这里插入图片描述

  • hashcode就是用来快速判断是否对等的(预判断)

隐私保护:

  • 前几年有一个网站,被脱裤了,
    • 技术的博客网站被脱裤了,被脱裤以后就有很多人说他们是用了明文存储,所以才导致用户的隐私被泄漏。这个是什么原因呢?
    • 首先,用户数据被盗,很容易理解,如果是明文存储,盗走的人将你的用户名和密码在别的网站不断尝试,就会导致很多用户信息被盗取。
    • 那么什么是非明文存储呢?就是服务器收到用户账号和密码以后,用md5转化后存储(下次登录就把传过来的密码md5加密转化一次以后再对照本地存储的密码),这样被盗走以后,他也没办法去其他网站登录。
  • 同时,有个东西叫加盐,什么叫加盐呢?
    • 那些黑客也在进步,我们觉得哪里比较难破解呢?因为hash不可逆,
    • 一,你拿到这个东西不能直接在网站登录验证,因为在转一次就是另外一个数值了;
    • 二,这个东西还没法逆向算出他的原密码。可是那些黑客时间多的是,他们把常用的密码一个一个存起来再映射,当他们盗了你们的库以后,逆推,比如密码是123456,md5转化后是ddddd,黑客们自己做一个md5映射表,就知道ddddd对应的原密码是123456了,这个暴力破解的映射表就叫彩虹表,可以一定程度上破解这种使用hash存储密码的方式。
    • 那么,使用加盐就可以破解这个东西。什么叫加盐,每个网站自己定义一个盐,这个盐是你严格保密的,不会被别人拿走,脱裤的时候被人把盐也拿走也挺惨的。盐是什么呢?盐就是你做md5或者sha1的时候,你不是用123456做hash,而是加个333,123456333,这个333就是你的盐,他的md5值就完全是另外一个值了。每个网站的盐都不一样,这样就导致彩虹表失效了。一般盐都不会是333,而是一长串非常规字符。

Hash是编码吗?

  • 不是,编码是什么?你编过去,编回来任何数据都不损失。hash是什么?hash是抽取你的特征,他不能逆向。

  • Hash是加密吗?据说MD5是不可逆加密?

    • 不是加密,百度百科都搞错了,他是一种不可逆的转化。
    • 还有人发明一个不可逆加密,听着很有道理。加密的意思就是把A格式改成B格式,别人看不懂,并且可以被还原。但是你硬是要把加密这两个字曲解成别的意思,他的意思是让别人看不懂,那我承认MD5是一种不可逆加密,但是加密这个词是有他自己的定义的,这个词不能乱说的。

9.Hash与非对称加密

在这里插入图片描述

  • 这是之前一个图,这个图有个缺点,他的签名数据和原数据是一样大的,因为签名数据可以还原回来呀。你文件小没关系,一个10G的视频,他的签名要10G那么大,想想就觉得好臃肿啊。事实上签名的做法,他们会对数据先进行hash,再进行签名,对那个hash值进行签名。 在这里插入图片描述

10.字符集

  • 含义:一个由整数向现实世界中的文字符号的Map

分支:

ASCII:

  • 128个字符,一个字节(可以使用256个,但是ASCII只用了其中128个)

ISO-8859-1:

  • 对ASCII进行扩充,一个字节

Unicode:

  • 13万字符,多字节
    • UTF-8:Unicode编码分支
    • UTF-16:Unicode编码分支
  • 什么叫编码分支呢?
    • 比如我有三个字:中国人
      • 其中“中”他可能对应的是00000001,
      • “国”对应的是00001111,
      • “人”对应的是11111111
    • 这是他们对应的编码,但是实际表达的时候我们可能不会这么写
      • 中01
      • 国001111
      • 人11111111
      • 短了一点,这个可能就是UTF-8
    • 另外一种方法,也许是
      • 中0001
      • 国1111
      • 人11111111
      • 这种可能是UTF-16
    • 就是他们的字符集可能一致,但是具体的编码方式可能不一致,这个就是不同的编码。当然上面这个例子是不对的,比如UTF-8和UTF-16有一个很明显的区别,UTF-16是16位表示一个字符,所以不存在上面这么短的,上面只是在举例子。

GBK

  • GBK/GBK2312/GBK18030:中国自研标准,多字节,字符集+编码