一文搞懂数据转换之摘要、编码、加密、签名

一.转义

转义的作用?

转义通常有两种功能。第一种是如果不进行转义就可能与语法规定的某些内容产生混淆,所以这些内容都被设计为需要转义。 第二种也叫字符引用,用于表示无法在当前上下文中被键盘录入的字符(如字符串中的回车符)。

第一种作用

以经典的JAVA语言中字符串中的字符转义为例。如果在一个字符串中存在一个"符号,那么就需要在"符号前添加\才能够正常的表示,比如下面这样:

String content="他说\"他需要休息\"";

之所以需要这样,是因为对于字符串来说,“本身就是表示一个字符串的起止符号。如果不进行转义,那么编译器将无法正确的识别其中的"哪些是分隔符,哪些是字符串内部的”。

第二种作用

回车符和换行符,再正常情况下,这样的字符是不可见的,对于这种字符,不采用转义的形式进行表达那么会比较困难。如果在一个字符串中存在回车符,那么就需要用\r表示。如果在一个字符串中存在换行符,那么就需要用\n表示。比如下面这样:

String content="床前明月光,/r/n疑是地上霜";

二. 编码解码

1. 什么是编码解码?

编码是采用一种新的载体来表示前一个载体所表达的信息。解码,是编码的逆过程。从概念上可以看出,编码本质上是信息形式的转化,没有保密的作用,因为编码和解码的算法是公开的,只要知道是什么编码的内容,任何人都可以轻松地解码。编码的目的不是为了加密信息,而是将信息转化成统一的格式,方便在不同系统之中传输。

信息->编码->二进制->解码->信息

2. 常见的编码方式

文本文件编码

将“文本数据”编码为“二进制数据”,以实现通过“二进制数据”进行存储或者传输的目的。文本文件在计算机中,最终的载体只能是二进制文件的形式存在。由于计算机诞生在美国,文本内容也只包含有英文内容。因此当时只要使用ASCII进行编码就可以了。但是后来随着计算机的普及,需要表达的信息越来越多了。因此诞生了UTF-8, UTF-16,UTF-32, Unicode, ISO8859-1, GBK, GB2312等等编码形式。在计算机领域,数据存储单位叫字节——byte,最小的存储单元的容量是1位-1bit。一个bit有两个状态 0 和 1。1byte = 8bit。通常,一个英文字母占1字节,汉字采用GBK编码时,占用2字节。UTF-8是可变长度编码,一般用 0-4 字节表示。

但不论如何,这些编码其实都是对文本信息的编码形式。

Base64编码

将“二进制数据”编码为“64个可打印字符的组合”,以实现通过“可打印字符的形式”进行存储或者传输的目的。无论是公钥证书,还是电子邮件数据,经常要用到Base64编码,那么为什么要做一下这样的编码呢?因为在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。 而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备, 由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。 所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。
使用场景:

  • 在Web场景中,在有些地方限制了数据传输的方式。例如,在URL,只能传递文本。因此,如果想要传输一组二进制数据(例如图片)。那么可以选用Base64编码,将二进制数据编码为可打印的字符串。这样才能完成URL上二进制数据的传输。
  • 对证书来说,特别是根证书,一般都是作Base64编码的,因为它要在网上被许多人下载。
  • 电子邮件的附件一般也作Base64编码的,因为一个附件数据往往是有不可见字符的。
URL编码

Url编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符从而达到适合传输的目的。例如:由于url只能使用英文字母、数字和某些标点符号,不能使用其他文字和符号,如果需要在URL中传递中文作为参数,或者需要在URL中传递空格、&、?、=等等特殊符号。这个时候就需要进行URL编码。编码的目的HTTP协议的内在要求,通过这种形式,可以浏览器表单数据的打包。

3. 乱码

一般,如果解码之后无法正确还原原来所表达的信息,此时就出现了乱码。例如,使用GB2312的方式去解码一个UTF8编码的文件,那么就会出现乱码。总的来说,乱码通常来说只是因为选用的解码方式和编码方式不同,而导致信息失真的情况。选用正确的编码就能够解读出正确的信息。

在编码或解码时,重点放在所有具有相同算法的人身上,并且该算法通常具有良好的文档记录、广泛的分布和相当容易实现的特点。任何人最终都能解码编码数据。

三. 摘要(哈希)

1. 什么是摘要?

摘要的目的是为了校验信息的完整性,保证信息在传输过程中不被篡改。例如我们下载一个压缩包后可以查看压缩包的MD5值。对比下载的压缩包MD5值和网站提供的MD5值,如果两个MD5值不一致,那么说明该压缩包不是官方提供的那个压缩包,可能被替换成其他文件或被修改过。摘要只是用于验证数据完整性和唯一性的哈希值,不管原始数据是什么样的,得到的哈希值都是固定长度的。也就是说摘要并不是原始数据加密后的密文,只是一个验证身份的令牌。所以我们无法通过摘要解密得到原始数据。

2. 哈希函数

散列函数(也叫哈希函数,哈希函数又称散列函数,杂凑函数,他是一个单向密码体制,即从明文到密文的不可逆映射,只有加密过程没有解密过程,哈希函数可以将任意长度的输入经过变化后得到固定长度的输出,这个固定长度的输出称为原消息的散列或消息映射。 理想的哈希函数可以针对不同的输入得到不同的输出,如果存在两个不同的消息得到了相同的哈希值,那我们称这是一个哈希碰撞),如果使用的是hash算法,在计算过程中原文的部分信息是丢失了的,所以是不可逆。

hash算法的目的:同样的一段数据通过hash函数总是能得到相同的摘要,不同的数据通过hash函数总是应该得到不同的摘要。hash的目的是理想化的,不管什么hash算法实际上总有特别小的概率会出现不同的原始数据通过hash函数可能会得到相同的结果,所以:越好的hash算法会将这个概率降到越低这个概率越低,黑客要通过手段碰撞出相同摘要的难度就越大。常见的算法有md5、 sha系列。

MD5

Md5是哈希算法的一种,Md5可以把任意数据转换为定长(或限制长度)数据的算法。哈希算法的设计目标本身就决定了,它在大多数时候都是不可逆的,即你经过哈希算法得出的数据,无法再经过任何算法还原回去。所以,既然不能将数据还原,所以也就不存在解密;既然不能解密,那么哈希的过程也就不是加密了。

使用场景
出于以上的这种特性,MD5常用来校验密码是否正确、校验下载文件是否完整无损:

  • 校验密码是否正确:将用户注册的密码MD5摘要后储存起来,待用户登录时将用户录入的密码MD5摘要,对比两次摘要后的信息是否相等,相等即密码正确。(一般会进行加盐处理)
  • 校验下载文件是否完整无损:我们常下载开源文件资源包时,可以看到网站上提供的该资源包的MD5,下载文件完毕后,可通过自己的程序或直接去一些网站上计算其MD5码,如果与官网上提供的一致,则表示文件完整无损。
SHA系列

sha系列有SHA2、SHA256、SHA512等,这些算法的复杂度相对要高(有兴趣的可以搜索相关的算法实现及进行学习)。

3. MD5的破解

MD5本质上不可逆,即不存在逆算法。MD5计算的过程中丢失了信息,一个MD5理论上的确是可能对应无数多个原文的,因为MD5是有限多个的而原文可以是无数多个。比如主流使用的MD5将任意长度的“字节串映射为一个128bit的大整数。也就是一共有2128种可能,大概是3.4*1038,这个数字是有限多个的,而但是世界上可以被用来加密的原文则会有无数的可能性。虽然MD5本质上不可逆但是大部分简单的字符串 通过MD5加密的话 某种程度上来说是"可逆"的。原因是因为很多简单字符串MD5计算后的值,实际上是可以通过查表法等方式得到MD5前的原始串。也就是说MD5只能碰撞,无法真正破解。因为大量信息在hash过程中损失掉了。常用的密码攻击方式 常用的密码攻击方式有字典攻击、暴力破解、查表法、反向查表法、彩虹表等。

  • 暴力破解:按照一定的顺序一个一个的去试
  • 字典攻击:把常用的密码做成字典,破解时先看字典里是否存在,有效加快破解速度
  • 查表法:使用一个大型字典,把每个p和对应的q都记录下来,按q做一下索引,直接查找匹配。
  • 彩虹表 :对于HASH的传统做法是把H(X)的所有输出穷举,查找,得出。而彩虹表则是使用散列链的方式进行。
4.MD5 加盐(salt)

123456的MD5码为e10adc3949ba59abbe56e057f20f883e。一般来说,MD5摘要的结果是128位的摘要信息,然后每4位用一个16进制字符表示,所以,MD5摘要的结果一般显示为32位的16进制。如果你的系统用MD5摘要,并且无加盐,还经常使用123456为测试密码,对这一串MD5码一定很熟悉。这一些MD5码就静静地躺在DB中待校验。如果数据库被暴露(比如拖库),坏人得到了这些MD5码,就可以通过常用密码与其MD5码的映射关系,轻而易举地翻译出大多数密码。所以,一般来说,我们需要对原始密码进行加盐,所谓加盐,就是按照一定规则扰乱原有字符串,然后再进行MD5摘要。这个规则,自己定义,并且一定保密。

为了防止被暴力破解,可以加个密码盐,这样的话暴力破解几乎是搞不定了,即使搞定了可能也因为过去太久时间而变的没有价值。

四. 加密解密

1. 加密的概念

数据加密的基本过程,就是对原来为明文文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为 “密文”。通过这样的途径,来达到保护数据不被非法人窃取、阅读的目的。对数据进行转换以后,数据变成了另一种格式,并且除了拿到解密方法的人,没人能把数据转换回来。维护数据机密性,即确保数据不会被预期收件人以外的任何人使用。例如你想给某人发送一封密信,或通过互联网给人发送密码,这些对隐秘性要求比较强的事情,就需要对信息进行加密。因此,加密通常用于网络通信。因为网络上的通信数据,任何人都有可能会拿到,把数据加密后再传送,送达以后由对方解密后再查看,就可以防止网络上的偷窥。

加密是可逆的,明文 + 秘钥 = 加密信息,加密信息能通过密钥被还原为原始信息。

2. 解密

加密的逆过程为解密,即将该编码信息转化为其原来数据 的过程。

3. 加密的种类

加密又分为对称加密非对称加密,区别在于在加密和解密信息时秘钥是不是同一个若加解密使用相同密钥,则称为对称密钥加密,否则称为非对称密钥加密

4. 对称加密

对称加密算法是应用较早的加密算法,又称为共享密钥加密算法。在对称加密算法中,使用的密钥只有一个,发送和接收双方都使用这个密钥对数据进行加密解密。这就要求加密和解密方事先都必须知道加密的密钥。
对称加密

  • 数据加密过程:在对称加密算法中,数据发送方将明文 (原始数据)加密密钥一起经过特殊加密处理,生成复杂的加密密文进行发送。

  • 数据解密过程:数据接收方收到密文后,若想读取原数据,则需要使用加密使用的密钥及`相同算法的逆算法对加密的密文进行解密,才能使其恢复成可读明文。
    优点
    对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。
    缺点
    交易双方都使用同样密钥,容易泄露导致密钥泄露,所以安全性得不到保证。

常见的对称加密有DES,3DES,AES,Blowfish,Twofish,IDEA,RC6,CAST5等。

DES加密

Data Encryption Standard,DES 加密算法出自 IBM 的研究,后来被美国政府正式采用,之后开始广泛流传。它的特点是数据加密标准,速度较快,适用于加密大量数据的场合。但近些年使用越来越少,因为 DES 使用 56 位密钥,以现代的计算能力,24 小时内即可被轻易破解

AES加密

AES的全称是Advanced Encryption Standard,意思是高级加密标准。它的出现主要是为了取代DES加密算法的,因为我们都知道DES算法的密钥长度是56Bit,因此算法的理论安全强度是2的56次方。比较容易被破解。而AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据,相对来说安全很多。完善的加密算法在理论上是无法破解的,除非使用穷尽法。使用穷尽法破解密钥长度在128位以上的加密数据是不现实的,也仅存在理论上的可能性。统计显示,即使使用目前世界上运算速度最快的计算机,穷尽128位密钥也要花上几十亿年的时间,更不用说去破解采用256位密钥长度的AES算法了。所以AES比较难被破解
AES加密

  1. 填充:
    AES是分组密码,分组密码也就是把加密明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。
    分组加密

上面说到AES算法在对明文加密的时候,并不是把整个明文整个加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。但是这里涉及到一个问题:假如一段明文长度是192bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding)。AES在不同的语言实现中有许多不同的填充算法,我们只举出集中典型的填充来介绍一下。

  • NoPadding:
    不做任何填充,但是要求明文必须是16字节的整数倍。

  • PKCS5Padding(默认):
    如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。

  • ISO10126Padding:
    如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字符数,其他字符填充随机数。

需要注意的是,如果在AES加密的时候使用了某一种填充方式,解密的时候也必须采用同样的填充方式。才能正确的完成解密。填充明文时,如果明文长度原本就是16字节的整数倍,那么除了NoPadding以外,其他的填充方式都会填充一组额外的16字节明文块。

  1. 模式:
    AES的工作模式,体现在把明文块加密成密文块的处理过程中。AES加密算法提供了五种不同的工作模式:ECB、CBC、CTR、CFB、OFB,模式之间的主题思想是近似的,在处理细节上有一些差别。这里只介绍各个模式的基本定义(有兴趣的可以自行搜索相应的内容阅读)。
  • ECB模式(默认):电码本模式
  • CBC模式:密码分组链接模式
  • CTR模式:计算器模式
  • CFB模式:密码反馈模式
  • OFB模式:输出反馈模式

同样的,如果在AES加密的时候使用了某一种工作模式,解密的时候也必须采用同样的工作模式。

5. 非对称加密

非对称加密算法,又称为公开密钥加密算法。它需要两个密钥,一个称为公开密钥 (public key),即公钥,另一个称为 私有密钥 (private key),即 私钥
非对称加密

  • 如果使用公钥对数据进行加密,只有用对应的私钥才能进行解密。
  • 如果使用私钥对数据进行加密,只有用对应的公钥才能进行解密。
  • 密钥是成对出现。使用一对“私钥-公钥”,用私钥加密的内容只有对应公钥才能解开。

常见的非对称加密有RSA、ESA、ECC等。

RSA加密

RSA名称来源于发明这个算法的三个人的姓氏组成,算法大致内容就是对极大整数进行因式分解。这种算法非常可靠,密钥越长,它就越难破解(有兴趣的可以搜索相关算法的实现进行研究)。根据已经披露的文献,目前被破解的最长 RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,目前还无法破解。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。目前主流的有RSA-1024, RSA-2048,RSA-4096等,数字代表的是密钥长度,密钥长度越长,安全性越高,但相应的性能会下降

RSA算法优点
  • 不需要进行密钥传递,提高了安全性。
  • 可以进行数字签名认证。
RSA算法缺点
  • 加密解密效率不高,一般只适用于处理小量数据(如:密钥)。
  • 容易遭受小指数攻击。

RSA算法提供了生成公钥和私钥的方法,注意是成对生成的!一般将公钥保存在客户端、私钥保存在服务端。黑客反编译可能拿到公钥,但是因为私钥存储在服务器,所以不用太担心泄密

在使用RSA加解密中必须考虑到的密钥长度明文长度密文长度的问题。明文长度需要小于密钥长度,而密文长度则等于密钥长度。因此当加密内容长度大于密钥长度时,有效的RSA加解密就需要对内容进行分段处理才能进行加密。因为,RSA算法本身要求加密内容也就是明文长度m必须0<m<密钥长度n。如果小于这个长度就需要进行padding(填充),因为如果没有padding(填充),就无法确定解密后内容的真实长度。只要用到padding(填充),那么就要占用实际的明文长度,而且这部分字节也是参与加密的。于是实际明文长度需要减去padding字节长度。例如:密钥默认是1024位,即1024位/8位-11=128-11=117字节。所以默认加密前的明文最大长度117字节,解密密文最大长度为128字。两者相差11字节是因为RSA加密使用到了填充模式(padding),即内容不足117字节时会自动填满,
我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等。

RSA加密中的Padding

严格地说RSA也是一种“块”加密/解密。加密前输入长度必须与“模”相同:不足需要填充(Padding);明文长度大于“密钥”长度,则需要“分组”,最后一组同样需要填充(Padding)。所以密钥的长度也大于加密明文的长度,因此RSA不适合加密大段文本一般用来加密一个对称加密的密钥,然后再用此对称加密密钥对大段文本加密。

  1. RSA_PKCS1_PADDING 填充模式,
    最常用的模式,当你选择 RSA_PKCS1_PADDING 填充模式时,如果你的明文不够 128 字节, 加密的时候会在你的明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样。对于加密后的密文,解密端使用相同的填充方式都能解密。解密后的明文也就是之前加密的明文。
  • 输入:必须 比 RSA 钥模长(modulus) 短至少11个字节, 也就是RSA_size(rsa) – 11如果输入的明文过长,必须切割,然后填充。
  • 输出:和密钥一样长。
  1. for RSA_NO_PADDING
    不填充模式,当在客户端选择 RSA_NO_PADDING 填充模式时,如果你的明文不够 128 字节, 加密的时候会在你的明文前面,前向的填充零。
    解密后的明文也会包括前面填充的零,这是服务器需要注意把解密后的字段前向填充的零去掉,才是真正之前加密的明文。
  • 输入:可以和RSA钥模长一样长,如果输入的明文过长,必须切割,然后填充。
  • 输出:和密钥一样长。
  1. RSA_PKCS1_OAEP_PADDING
    是 PKCS#1 推出的新的填充方式,安全性是最高的,和前面 RSA_PKCS1_PADDING 的区别就是加密前的编码方式不一样
  • 输入:RSA_size(rsa) – 41。
  • 输出:和密钥一样长。

不同的填充方式加解密也是不同的,使用的时候要注意

五.数字签名和验签

1. 数字签名

A:数字签名技术是将明文进行特定HASH函数得到的摘要信息(消息完整性),再将摘要信息用A的私钥加密(身份认证),得到数字签名,将密文和数字签名一块发给B。

B:收到A的消息后,先将密文用自己的私钥解密,得到明文。将数字签名用A的公钥进行解密后,得到正确的摘要(解密成功说明A的身份被认证了)。
对明文进行摘要运算,得到实际收到的摘要,将两份摘要进行对比,如果一致,说明消息没有被篡改(消息完整性)。

2. 数字签名的作用

  • 一是能确定消息的不可抵赖性,因为他人假冒不了发送方的私钥签名。发送方是用自己的私钥对信息进行加密的,只有使用发送方的公钥才能解密。
  • 二是数字签名能保障消息的完整性。一次数字签名采用一个特定的哈希函数,它对不同文件产生的数字摘要的值也是不相同的。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值