1.Java 加解密技术系列之 BASE64

2023-07-29,,

Java 加解密技术系列之 BASE64

序号
背景
正文
总结

这段时间,工作中
用到了 Java 的加解密技术,本着学习的态度,打算从这篇文章开始,详细的研究一番 Java
在加解密技术上有什么与众不同,同时,也想为大家或者自己留下点什么,一块分享这其中的“精髓”。需要说明的是,这个系列可能要持续一段时间,因为,加解
密的相关技术太多太多了,要搞明白这些着实不是一件容易的事。

背景

说到这个加解密技
术,之前一直没有机会研究这个东西,这次公司里的项目需要加解密的支持,因此有机会能够好好研究这一块。刚开始写的时候,还在考虑是写一篇文章还是写一个
系列,后来我发现,加解密这块的东西很多,如果一篇文章的话,就我现在这种水平,还远远不能一篇以序之,所以,还是决定采用细嚼慢咽的方式,来一点一点的
消化。

正文

废话说了很多,终于要进正题了。
其实,严格来说,BASE64 是一种编码的方式,并不是真正意义上的加解密,不过,从另一个角度来考虑的话,就是把数据变为人不会用肉眼能分辨其真实性的角度来说,BASE64 也是属于加解密范畴的。而且,有的加密技术,也是需要通过 BASE64 来编码转换的。
那么,BASE64 到底是什么呢?下面我来大概的介绍一下 BASE64 的编码原理。
BASE64
的编码都是按字符串长度,以每 3 个 8 bit 的字符为一组,然后针对每组,首先获取每个字符的 ASCII 编码,然后将 ASCII
编码转换成 8 bit 的二进制,得到一组 3*8=24 bit 的字节。然后再将这 24 bit 划分为 4 个 6 bit 的字节,并在每个
6 bit 的字节前面都填两个高位 0,得到 4 个 8 bit 的字节,然后将这 4 个
8 bit 的字节转换成十进制,对照 BASE64 编码表 (下表),得到对应编码后的字符。
注:1. 要求被编码字符是8bit的,所以须在ASCII编码范围内,\u0000-\u00ff,中文就不行。
  2. 如果被编码字符长度不是3的倍数的时候,则都用0代替,对应的输出字符为=

原理讲清楚了,下面举两个例子说明一下。
a) 字符长度为能被3整除时:比如“Tom” :

所以,btoa('Tom') = VG9t,也就是说,“Tom”的 BASE64 编码结果为 VG9t。
b) 字符串长度不能被3整除时,比如“Lucy”:

由于 Lucy
只有 4 个字母,所以按 3 个一组的话,第二组还有两个空位,所以需要用 0 来补齐。这里就需要注意,因为是需要补齐而出现的
0,所以转化成十进制的时候就不能按常规用 BASE64 编码表来对应,所以不是 a, 可以理解成为一种特殊的“异常”,编码应该对应“=”。

结束语

通过我上边说的这
些,我想你已经了解了 BASE64 编码的原理,当然,如果你现在去看 Java 中有关 BASE64
编码源码的话,我想你一定能很快就搞明白的。不过,在此之前,推荐你还是要亲自试一下,用程序编码一个单词,然后使用上边提到的原理,人工编码相同的单
词,你就会更加清楚是怎么回事。
顺带说一句,工作中,不能因为有了计算机,就什么事都要依赖它。有一句话,我想大家都知道,“用进废退”,就是这个道理。核心的东西掌握了,再来借助计算机,那就是事半功倍了,否则只会沦为高科技时代的奴隶。


1.Base64将输入的字符串或一段数据编码成只含有{'A'-'Z', 'a'-'z', '0'-'9', '+', '/'}这64个字符的串,'='用于填充。

2.作用

首先这算法是编码, 不是压缩, 编码后只会增加字节数;
算法简单, 几乎不会影响效率;
算法可逆, 解码很方便, 不用于私密信息通信;
虽然解码方便, 但毕竟编码了, 肉眼还是不能直接看出原始内容;
加密后的字符串只有[0-9a-zA-Z+/=], 不可打印字符(包括转移字符)也可传输;

3.Base64主要用于将不可打印的字符转换成可打印字符,或者简单的说将二进制数据编码成ASCII字符。

将二进制数据编码成ASCII字符主要的目的是能在纯文本内容中插入二进制数据,常见的应用场景包括:

    电子邮件

    这个可参考阮一峰的《MIME笔记》

    微软的MHT格式

    这是模仿邮件格式将多种资源打包在一个文件中的格式,所有二进制资源都采用 Base64 编码。

    XML文件

    这是一个纯文本文件,如果要基于 XML 格式设计可以保存图片或其它附件的数据格式,那就需要将这些二进制数据转码成 ASCII 字符。

    DATA URL

    最近流行起来的 Data URL,要在URL中使用二进制数据,当然也只能进行 ASCII 编码


编解码:Base64编码在URL中的应用

项目查询背景:目前项目中,本地文件全部使用UTF-8进行编码,Android网络访问全部采用Base64加密传输,因此考虑Base64和Url编码是否会有冲突,查询的结果是没有冲突,可以直接放在Url中稳定传输。

以下是查询的结果,方便以后查询。

Base64编码详解:http://www.cnblogs.com/lifesting/archive/2012/07/12/2587923.html

以下内容引用地址:http://hi.baidu.com/westfruit/item/bc09df16c7ae5d761009b5d6

Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串, 用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短, 同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
  然而,标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
 
 为解决此问题,可采用一种用于URL的改进Base64编码,它不在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“*”和
“-”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
  另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
  此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。 []在迅雷下载地址中的应用  很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
  如thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
  其实迅雷的“专用地址”也是用Base64加密的,其加密过程如下:
  一、在地址的前后分别添加AA和ZZ
  如www.baidu.com/img/sslm1_logo.gif变成
  AAwww.baidu.com/img/sslm1_logo.gifZZ
  二、对新的字符串进行Base64编码
  如AAwww.baidu.com/img/sslm1_logo.gifZZ用Base64编码得到
  QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
  三、在上面得到的字符串前加上“thunder://”就成了
  thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==


有时候我们需要使用一个URL作为URL地址的参数来传递,假如我们需要传递的URL含有参数,例如:

/shopping/confirm.action?id=1&name=itzhai

那么按照如下的方法传送,那么,参数会丢失:

www.itzhai.com/submit.action?url=/shopping/confirm.action?id=1&name=itzhai;

为了能正常的传递参数,我们可以使用Base64对URL进行编码后再传递,接收到时再进行解码,这样就可以正确获取到传递的URL了。下面是基本的代码:

引入Jar包

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

为URL编码:

String url = "/shopping/confirm.action?id=1&name=itzhai";
String code = new String(Base64.encode(url.getBytes()));

这样获得的code为:

L3Nob3BwaW5nL2NvbmZpcm0uYWN0aW9uP2lkPTEmbmFtZT1pdHpoYWk=

然后接受到该code时,就可以为URL解码了:

String url = new String(Base64.decode("L3Nob3BwaW5nL2NvbmZpcm0uYWN0aW9uP2lkPTEmbmFtZT1pdHpoYWk="));

本文链接:http://www.itzhai.com/base64-encoding-in-java-using-a-url-as-a-url-parameter.html

转自-http://blog.csdn.net/happylee6688/article/details/43950521

1.Java 加解密技术系列之 BASE64的相关教程结束。

《1.Java 加解密技术系列之 BASE64.doc》

下载本文的Word格式文档,以方便收藏与打印。