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


    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字符主要的目的是能在纯文本内容中插入二进制数据,常见的应用场景包括:

    1. 电子邮件

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

    2. 微软的MHT格式

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

    3. XML文件

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

    4. 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://blog.csdn.net/happylee6688/article/details/43950521

  • 相关阅读:
    2.ECMAScript 5.0
    1.Javascript简介
    9.定位
    HDU2032 杨辉三角
    HDU2058 The sum problem
    HDU2091 空心三角形
    HDU1166 敌兵布阵(树状数组模板题)
    HDU2049 不容易系列之(4)——考新郎
    Python网络爬虫与信息提取(三)(正则表达式的基础语法)
    HDU6576 Worker
  • 原文地址:https://www.cnblogs.com/crazylqy/p/5178029.html
Copyright © 2020-2023  润新知