zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Struts2+Spring3+Mybatis3开发环境搭建
    spring+struts2+mybatis
    【LeetCode】Populating Next Right Pointers in Each Node
    【LeetCode】Remove Duplicates from Sorted Array
    【LeetCode】Remove Duplicates from Sorted Array II
    【LeetCode】Binary Tree Inorder Traversal
    【LeetCode】Merge Two Sorted Lists
    【LeetCode】Reverse Integer
    【LeetCode】Same Tree
    【LeetCode】Maximum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/crazylqy/p/5178029.html
Copyright © 2011-2022 走看看