什么是数据安全?假如Bob要给Alice发送一封邮件,在发送邮件的过程中,黑客可能会窃取到邮件的内容,所以我们需要防窃听;黑客也有可能会篡改邮件的内容,所以Alice必须要有能有去识别邮件是否被篡改;最后,黑客也可能假冒Bob给Alice发送邮件,所以Alice还必须有能力识别出伪造的邮件。所以数据安全的几个要点就是:防窃听、防篡改和防伪造。
古代的加密方式:
移位密码:HELLO => IFMMP (把英文字母按顺序往后移动几位,这里就是HELLO中的每个字母向后移动一位,就变成了IFMMP)
替代密码:HELLO => p12,5,3(用某个书籍的某一页某一行的第几个单词来记录信息)
现代计算机加密:
建立在严格的数学理论基础上
密码学逐渐发展成一门科学
总结:
设计一个安全的加密算法非常困难
验证一个加密算法是否安全更加困难
当前被认为安全的加密算法仅仅是迄今为止尚未被攻破
不要自己去设计加密算法
不要自己去实现加密算法
不要自己修改已有的加密算法
编码算法ASCII编码就是一种编码,部分编码如下:
字母 编码(16进制)A 0x41
B 0x42
C 0x43
D 0x44
... ...
汉字使用不同的编码算法,得到的编码是不一样的,汉字是使用Unicode编码后是两个字节,经过UTF-8编码后得到三个字节:
汉字 Unicode编码 UTF-8编码中 0x4e2d 0xe4b8ad
文 0x6587 0xe69687
编 0x7f16 0xe7bc96
码 0x7801 0xe7a081
... ... ...
URL编码是浏览器发送数据给服务器时使用的编码:
key1=value1&key2=value2&key3=value3
q=%E4%B8%AD%E6%95%87
URL编码规则:
A~Z,a~z,0~9以及-_.*保持不变
其它字符以%xx(以%开头的16进制来表示)
<: %3C
中:%E4%B8%AD (正好对应UTF-8编码的16进制: 0xe4b8ad)
public static void main(String[] args) throws Exception { String orginal = "URL 参数"; // URL 编码 String encode = URLEncoder.encode(orginal, "UTF-8"); System.out.println(encode); // URL+%E5%8F%82%E6%95%B0 // URL解码 String decode = URLDecoder.decode(encode, "UTF-8"); System.out.println(decode); // URL 参数 } 通过运行结果可以看到:URL编码英文字母保持不变,空格编码为"+",一个中文经过UTF-8编码后,通常是以%开头的16进制编码。
总结:URL编码是编码算法,不是加密算法;URL编码的目的是把任意文本数据编码为%前缀表示的文本,编码后的文本仅包含A~Z,a~z,0~9,-_.*,%,便于浏览器和服务器处理。
Base64编码:一种把二进制数据用文本表示的编码算法,例如我们有一个字节数组byte[]{0xe4,0xb8,0xad},通过Base64编码后得到的字符串为"5Lit"。如何使用Base64进行编码?假如我们把汉字“中”用UTF8表示的字节表示出来,它就是{0xe4,0xb8,0xad},这三个字节就是24位(11100100 10111000 10101101),我们把这24位按照每6位分组就形成4个字节,这四个字节对应的16进制就是{0x39,0x0b,0x22,0x2d},通过查表就可得到分别对应的是{5,L,i,T},所以最终编码出来的字符串就是5LiT。Base64对应的编码表从索引0开始,如下:
索引 编码 索引 编码 索引 编码 索引 编码0 A 25 Z 51 z 61 9
1 B 26 a 52 0 62 +
2 C 27 b 53 1 63 /
3 D 28 c 54 2
... ... ... ... ... ...
使用Base64编码的目的:一种用文本(A~Z,a~z,0~9,+/=)表示二进制内容的方式,适用于文本协议,但效率会下降(因为二进制经过Bse64编码长度会增加1/3),应用比如电子邮件协议。如果数组的长度不是3的整数倍,末尾补0x00或0x00 0x00,编码后加=表示补充了一个字节,编码后加==表示补充了2个字节。在解码时就可以去掉补充的字节。
public static void main(String[] args) throws UnsupportedEncodingException { String orignal = "Hello\u00ff编码测试"; // String b64 = Base64.getEncoder().encodeToString(orignal.getBytes("UTF-8")); //去掉等号,实际上有没等号在解码时是不影响的 String b64 = Base64.getEncoder().withoutPadding().encodeToString(orignal.getBytes("UTF-8")); System.out.println(b64); String ori = new String(Base64.getDecoder().decode(b64), "UTF-8"); System.out.println(ori); //实现URL的Base64编码和解码 String urlB64 = Base64.getUrlEncoder().withoutPadding().encodeToString(orignal.getBytes("UTF-8")); System.out.println(urlB64); String urlOri = new String(Base64.getUrlDecoder().decode(urlB64), "UTF-8"); System.out.println(urlOri); //在Java中,使用URL的Base64编码,它会把"+"变为"-",把"http://www.likecs.com/"变为"_",这样我们在传递URL参数的时候,就不会引起冲突 }总结:Base64是编码算法,不是加密算法;Base64编码的目的是把任意二进制数据编码为文本(长度增加1/3);其它编码:Base32,Base48,Base58
摘要算法