一.转义
转义的作用?
转义通常有两种功能。第一种是如果不进行转义就可能与语法规定的某些内容产生混淆,所以这些内容都被设计为需要转义。 第二种也叫字符引用,用于表示无法在当前上下文中被键盘录入的字符(如字符串中的回车符)。
第一种作用
以经典的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是分组密码,分组密码也就是把加密明文分成一组一组
的,每组长度相等,每次加密一组数据,直到加密完整个明文。在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字节明文块。
- 模式:
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不适合加密大段文本
,一般用来加密一个对称加密的密钥,然后再用此对称加密密钥对大段文本加密。
-
RSA_PKCS1_PADDING 填充模式,
最常用的模式,当你选择 RSA_PKCS1_PADDING 填充模式时,如果你的明文不够 128 字节, 加密的时候会在你的明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样
。对于加密后的密文,解密端使用相同的填充方式都能解密。解密后的明文也就是之前加密的明文。
- 输入:必须 比 RSA 钥模长(modulus) 短至少11个字节, 也就是RSA_size(rsa) – 11如果输入的明文过长,必须切割,然后填充。
- 输出:和密钥一样长。
-
for RSA_NO_PADDING
不填充模式,当在客户端选择 RSA_NO_PADDING 填充模式时,如果你的明文不够 128 字节, 加密的时候会在你的明文前面,前向的填充零。
解密后的明文也会包括前面填充的零,这是服务器需要注意把解密后的字段前向填充的零去掉,才是真正之前加密的明文。
- 输入:可以和RSA钥模长一样长,如果输入的明文过长,必须切割,然后填充。
- 输出:和密钥一样长。
-
RSA_PKCS1_OAEP_PADDING
是 PKCS#1 推出的新的填充方式,安全性是最高的,和前面 RSA_PKCS1_PADDING 的区别就是加密前的编码方式不一样
- 输入:RSA_size(rsa) – 41。
- 输出:和密钥一样长。
不同的填充方式加解密也是不同的,使用的时候要注意
五.数字签名和验签
1. 数字签名
A:数字签名技术是将明文进行特定HASH函数得到的摘要信息(消息完整性),再将摘要信息用A的私钥加密(身份认证),得到数字签名,将密文和数字签名一块发给B。
B:收到A的消息后,先将密文用自己的私钥解密,得到明文。将数字签名用A的公钥进行解密后,得到正确的摘要(解密成功说明A的身份被认证了)。
对明文进行摘要运算,得到实际收到的摘要,将两份摘要进行对比,如果一致,说明消息没有被篡改(消息完整性)。
2. 数字签名的作用
- 一是能确定消息的不可抵赖性,因为他人假冒不了发送方的私钥签名。发送方是用自己的私钥对信息进行加密的,只有使用发送方的公钥才能解密。
- 二是数字签名能保障消息的完整性。一次数字签名采用一个特定的哈希函数,它对不同文件产生的数字摘要的值也是不相同的。
网友评论