文档章节

Java加密解密(二) Base64编码

pseudo
 pseudo
发布于 2015/06/12 13:18
字数 1113
阅读 1081
收藏 25
点赞 0
评论 0

1. Base64的由来

Base64最早用于解决电子邮件传输问题。由于“历史问题”,早期的电子邮件网关只允许传输ASCII(二进制为00000000-01111111)字符,如果有非ASCII字符经过这种网关时, 字符的二进制位可能会被篡改(如将10000001改为00000001)。由此产生了Base64编码来保证非ASCII字符的传输。

2. 原理

Base64顾名思义是一种基于64个字符的编码算法。 如下是Base64的字符映射表,详情参见RFC 2045

|Value|Encoding||Value|Encoding||Value|Encoding||Value|Encoding| |---|---| |0|A||17|R||34|i||51|z| |1|B||18|S||35|j||52|0| |2|C||19|T||36|k||53|1| |3|D||20|U||37|l||54|2| |4|E||21|V||38|m||55|3| |5|F||22|W||39|n||56|4| |6|G||23|X||40|o||57|5| |7|H||24|Y||41|p||58|6| |8|I||25|Z||42|q||59|7| |9|J||26|a||43|r||60|8| |10|K||27|b||44|s||61|9| |11|L||28|c||45|t||62|+| |12|M||29|d||46|u||63|/| |13|N||30|e||47|v| |14|O||31|f||48|w||(pad)|=| |15|P||32|g||49|x| |16|Q||33|h||50|y|

其中的value是10进制的值,Encoding是与之相对应的编码字符

因为Base64中共有64个字符,所以只需要6个bit就可以表示一个base64字符(1<<6=64)。另外,由于计算机基本处理单位为字节,所以字符编码是以字节为单位对字符进行编码,比如,字符'A'的ASCII编码为01000001,汉字'你'的UTF-8编码为11100100 10111101 10100000, GBK编码为11000100 11100011。由此,Base64的编码步骤如下: step1 将待转码字符串以某种编码格式(如UTF-8)进行编码,得到一个字节数组 step2 将字节数组按三个字节为一组进行分组(24个bit) step3 将每个分组按6 bit进行划分(不足6位时低位补0),得到N(2<=N<=4)个6位二进制码(以下称为Base64编码单元)。 step4 将每个Base64编码单元转换为10进制值,并根据上表得到相应的Base64编码字符,不足4个编码单元的分组要用=进行填充。

例:

Base64编码过程-
原始字符串我x
UTF-8编码,分组0xe6, 0x88, 0x91; 0x78
二进制表示11100110, 10001000, 10010001; 01111000
划分编码单元111001,101000,100010,010001; 011110,00 00000(补位)
Value57,40,34,17; 30,0
对应Encoding5,o,i,R; e,A, ***=***,***=***(填充符)
最终结果5oiReA==

3. 用途

  1. 保存二进制数据,如密钥等。
  2. 使用Http协议在url中传输二进制数据。 将Base64编码中不符合URL规定的字符替换成其他合法的字符,并去掉回车换行就得到了UrlBase64编码。经过UrlBase64编码,就可以将二进制参数直接放在url中。 这些功能也可以用hex编码实现,但base64编码的结果要比hex结果短。

4. 实现

jdk中的类sun.misc.BASE64Encodersun.misc.BASE64Decoder提供了Base64的编码解码实现,但jdk中sun开头的包是sun公司的内部实现,该包下的代码不保证与其他jave平台的兼容性(见Why Developers Should Not Write Programs That Call 'sun' Packages),所以需要使用第三方实现,也可将这两个类复制到自己的代码中。 笔者测试环境中使用的maven依赖如下:

    <!--bouncycastle依赖-->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk16</artifactId>
        <version>1.46</version>
    </dependency>
    <!--commons-codec-->
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.10</version>
    </dependency>

4.1 BouncyCastle实现

org.bouncycastle.util.encoders下提供了工具类Base64,UrlBase64与Hex用于Base64,UrlBase64与hex编码/解码操作。

final String charset="UTF-8";
String input="Base64编/解码";
//编码
String encoded=new String(Base64.encode(input.getBytes(charset)),"ASCII");
String urlSafeEncoded=new String(UrlBase64.encode(input.getBytes(charset)),"ASCII");
//解码
Assert.assertEquals(input,new String(Base64.decode(encoded),charset));
Assert.assertEquals(input,new String(UrlBase64.decode(urlSafeEncoded),charset));

4.2 commons-codec实现

工具类org.apache.commons.codec.binary.Base64提供了Base64与UrlBase64的编码解码方法。

final String charset="UTF-8";
String input="Base64编/解码";
String encoded= Base64.encodeBase64String(input.getBytes(charset));
String urlSafeEncoded=Base64.encodeBase64URLSafeString(input.getBytes(charset));
Assert.assertEquals(input, new String(Base64.decodeBase64(encoded), charset));
Assert.assertEquals(input, new String(Base64.decodeBase64(urlSafeEncoded), charset));

4.3 BouncyCastle与commons-codec区别

标准Base64编码后的字符串每76个字符为一行(称为分块),行尾要添加一个回车换行符"\r\n"。但bouncycastle并没有这样做,而commons-codec支持标准实现,但默认并没有使用。

++++++++++++BouncyCastlecommons-codec
标准(分块)编码不支持Base64.encodeBase64ChunkedBase64.encodeBase64(binaryData, true)
UrlBase64没有回车换行,'+'变为'-', '/'变为'_', '='变为'.'与bouncyCastle相同,但去掉了填充符

© 著作权归作者所有

共有 人打赏支持
pseudo

pseudo

粉丝 74
博文 37
码字总数 35469
作品 3
朝阳
程序员
Android外部文件加解密及应用实践

有这样的应用场景,当我们把一些重要文件放到asset文件夹中时,把.apk解压是可以直接拿到这个文件的,一些涉及到重要信息的文件我们并不想被反编译拿去,这个时候需要先对文件进行加密,然后...

C6C ⋅ 05/08 ⋅ 0

基于ClassLoader的java代码加密的经验分享

原理就是 生成项目时将待加密的java class文件通过加密算法转换生成加密的二进制文件,此文件不会被JD-GUI等反编译工具直接解密。 项目在启动时,用自定义的ClassLoader将加密的二进制文件进...

hxt168 ⋅ 06/06 ⋅ 0

Common Gui Tools 1.4 发布,Java GUI 实用小工具集

Java GUI实用小工具集 Common Gui Tools 新增:二维码生成解析、时间戳转换、Json格式化、文本文件切分等。 Common Gui Tools 是用java编写,GUI界面的实用小工具集,1.4版有20个小工具: 1,...

bs2004 ⋅ 04/22 ⋅ 0

SpringBoot 整合 oauth2(三)实现 token 认证

关于session和token的使用,网上争议一直很大。 总的来说争议在这里: session是空间换时间,而token是时间换空间。session占用空间,但是可以管理过期时间,token管理部了过期时间,但是不占...

FantJ ⋅ 05/14 ⋅ 0

微信小程序开发实战1:通过shareTicket获取分享群的OpenGId

玩过微信小程序的都知道,如果有群排行就必然要获取群的唯一id(OpenGId)。 但是OpenGId的获取必须通过加密数据:encryptedData、加密向量iv获取,对于encryptedData的解密微信官方提供了P...

qicong88 ⋅ 05/18 ⋅ 0

那些提升开发人员工作效率的在线工具

点击上方“程序员小灰”,选择“置顶公众号” 有趣有内涵的文章第一时间送达! 本文转载自公众号 Hollis 作为一个Java开发人员,经常要和各种各样的工具打交道,除了我们常用的IDE工具以外,...

bjweimengshu ⋅ 04/18 ⋅ 0

Java GUI实用小工具集 - Common Gui Tools

Common Gui Tools 是用java编写,GUI界面的实用小工具集,1.4版有20个小工具: 1,编码转换:Character Converter 2,加密解密:Encrypt And Decrypt 3,计算文件数字签名:File Digital Si...

bs2004 ⋅ 2013/03/20 ⋅ 3

整理的AES对称加密和RSA非对称加密

项目用到这两个加密方法,就整理了下做了个demo,这里也贴出来代码供参考 AES加密解密 public class AESUtil { 生成AES密钥 @param strkey @return @throws Exception AES加密,传入需要加密...

andrewniu ⋅ 05/11 ⋅ 0

Java序列化之Serializable

1.需求 1.什么是Java序列化 2.详解 1.序列化 理解为"打碎"即可 2.在书本上序列化的意思是将Java对象转为二进制 3.java平台允许我们在内存中创建对象,当JVM运行时对象才能存在,如果JVM停止,对...

村长大神 ⋅ 05/08 ⋅ 0

YMP v2.0.5 发布,轻量级 Java 应用开发框架

YMP v2.0.5 发布了。本次版本更新主要是新增若干新特性、增加对Beetl模板引擎的支持,同时针对框架问题修复、移除编译警告及性能优化,并对依赖包升级更新。 YMP是一个非常简单、易用的轻量级...

有理想的鱼 ⋅ 04/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

微信小程序接口文档

API接口文档:http://developers.weixin.qq.com/miniprogram/dev/api/

熊二的爸爸是谁 ⋅ 32分钟前 ⋅ 0

优先考虑类型安全的异构容器(29)

1、泛型常用于集合(Set、Map)以及单元素容器(ThreadLocal、AtomicReference) 被参数化的容器:只能有固定数目的类型参数 2、Class 类在jdk 1.5 之后被泛型化了 String.class 属于Class<S...

职业搬砖20年 ⋅ 41分钟前 ⋅ 0

Linux下date格式化

最近在编辑一个脚本时,发现对Linux下时间的命令理解的不是很透彻,看到一篇关于date时间格式化的文章,遂摘录了下来。 本文取自:Linux下date命令,格式化输出,时间设置 一、date命令 [ro...

blackfoxya ⋅ 42分钟前 ⋅ 0

动手---sbt (1)

1:https://github.com/ucb-bar/chisel3 下载源码 2:Chisel-Tutorial文件夹下的readme.md文件中有说明: a)需要先测试是否安装了sbt并做一个hello工程 joe@joe-Aspire-Z3730:/media/sdb4/dow...

whoisliang ⋅ 43分钟前 ⋅ 0

Micropython实例之TPYBoardv102位数码管显示实验

import pybfrom pyb import Pin #数码管a~g dp对应的开发板引脚d_Pins=[Pin(i,Pin.OUT_PP) for i in ['X1','X2','X3','X4','X5','X6','X7','X8']]#数码管位段1 2 3 4对应的引脚w...

bodasisiter ⋅ 46分钟前 ⋅ 0

Java WebService接口生成和调用 图文详解

webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所...

Dylan1009 ⋅ 50分钟前 ⋅ 0

iOS类大小的测量

iOS中,测量类的大小可以用函数malloc_size (头文件#import <malloc/malloc.h>) 比如我们新建一个继承与object的类 代码: testObjest *test = [testObjest alloc]; NSLog(@"-----%...

RainOrz ⋅ 51分钟前 ⋅ 0

android支付宝首页、蚂蚁森林效果、视频背景、校园电台、载入收缩动画等源码

Android精选源码 android实现蚂蚁森林效果源码 android仿支付宝首页应用管理(拖拽排序,添加删除) android校园网络电台客户端源码 android实现按钮伸缩效果源码 一款仿iOS的PickerView控件,...

逆鳞龙 ⋅ 58分钟前 ⋅ 0

阿里云Apsara Block Storage企业级分布式块存储产品

摘要: Apsara Block Storage是阿里云推出的一款企业级分布式块存储产品,帮助企业市场头部客户构建高性能、弹性、可靠的大规模横向扩展云存储服务平台。可对接各种类型计算平台,包括阿里云...

阿里云云栖社区 ⋅ 今天 ⋅ 0

spring AOP

1. 添加MAVEN <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>sprin......

BobwithB ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部