Java加密与安全

  什么是数据安全?假如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

摘要算法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpypfg.html