Android数据安全之Base64编码

Base64在平常开发中很常用,有些人认为Base64也算是一种加密算法,但我觉得严格意义上讲算是一种编码方式。只不过将明文按照特定的字节划分转换成暗文,并算不上是加密。因为如果真的拿来作为重要数据的加密方式的话,破解起来容易。当然这个见仁见智,以上仅仅是个人的理解。

定义

Base64是一种将二进制数据转成文本数据的方案,Base64编码本质上就是一种基于64个可打印字符来表示二进制数据的表示方法。
对于非二进制数据,是先将其转换成二进制形式,然后再转成文本数据。之所以叫base64,是因为无论明文是什么(比如汉字,特殊符号等),编码后只会变成字母A-Z、a-z和0-9 和+和/这64个字符,同时体积一般也会变成原来的4/3。

背景

在计算机中任何数据都是按ascll码存储的,而ascll码的128~255之间的值是不可见字符。比如图片二进制流的每个字节不可能全部是可见字符。而且在网络上交换数据时(以传统的邮件传送为例,它只支持可见字符的传送),比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。

应用场景

1.把一些对象转换成String形式保存或者传输,比如上传图片,上传语音
2.传输的数据不希望明文传输
3.配合加密,即将加密后的字节数组转换成String形式

编码原理

 通过查看Base64的索引表,字符选用了”A-Z、a-z、0-9、+、/” 64个可打印字符。数值代表字符的索引,这个是标准Base64协议规定的,不能更改。64个字符用6个bit位就可以全部表示,需要注意的是一个Base64字符是8个bit,但是有效部分只有右边的6个bit,左边两个永远是0。
 
Base64编码表

下面举个例子,简单而言,对AST这个字符进行Base64编码:


1.首先先将每个字符换成10进制ASCII码,然后转成2进制,少位用0补齐,保证8位。

2.因为ASCII码大小是一字节也就是8位,3个8位。又因为3*8=4*6,我们给他分成4分,每份6位。如果少位都用0补齐。

3.把6位码前2位加两个0,比如010000转完后就是00010000,查找对于的十进制数,同时这个也是上表中的索引值。

4.根据索引值按照RFC里的BASE64标准查找换算,这样我们就得到了QVNU,也就是AST加密的结果。

代码实现

1.)字符串进行Base64编码

String encodedString = Base64.encodeToString("Base64编码".getBytes(), Base64.DEFAULT);
Log.e("Base64", "Base64---->" + encodedString);

2.)字符串进行Base64解码


String decodedString =new String(Base64.decode(encodedString,Base64.DEFAULT));
Log.e("Base64", "Base64---->" + decodedString);

3.)对文件进行Base64编码

File file = new File("/storage/emulated/0/pimsecure_debug.txt");
FileInputStream inputFile = null;
try {
    inputFile = new FileInputStream(file);
    byte[] buffer = new byte[(int) file.length()];
    inputFile.read(buffer);
    inputFile.close();
    encodedString = Base64.encodeToString(buffer, Base64.DEFAULT);
    Log.e("Base64", "Base64---->" + encodedString);
} catch (Exception e) {
    e.printStackTrace();
}

4.)对文件进行Base64解码

File desFile = new File("/storage/emulated/0/pimsecure_debug_1.txt");
FileOutputStream  fos = null;
try {
    byte[] decodeBytes = Base64.decode(encodedString.getBytes(), Base64.DEFAULT);
    fos = new FileOutputStream(desFile);
    fos.write(decodeBytes);
    fos.close();
} catch (Exception e) {
    e.printStackTrace();
}

5.)对图片进行Base64处理

//将图片Base64编码为字符串
 private void saveIconData() {
     //1. 准备图片,获取图片的bitmap对象
     Bitmap iconBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
     //2. 把bitmap图片压缩输出
     /**bitmap压缩输出 * format:压缩格式* quality:压缩的质量  0-100* stream:输出流*/
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     iconBitmap.compress(Bitmap.CompressFormat.PNG, 50, baos);
     //3. 通过base64 byte[]转成String
     String iconBase64Str = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
     Log.d("TAG:" + TAG, "----图片经base64编码后 :" + iconBase64Str);
     tvEncodeStr.setText(iconBase64Str);
     //4. 通过SharedPreferences保存icon的字符串
     sp.edit().putString("icon", iconBase64Str).apply();
 }

 //解码还原图片
 private void showIconData(String iconStr) {
     //5. 通过Base64解码icon的字符串
     byte[] decodeIcon = Base64.decode(iconStr, Base64.DEFAULT);
     //6. 把字节数组解码为bitmap位图对象
     Bitmap iconBitmap = BitmapFactory.decodeByteArray(decodeIcon, 0, decodeIcon.length);
     ivIcon.setImageBitmap(iconBitmap);
 }

6.)针对Base64.DEFAULT参数说明

无论是编码还是解码都会有一个参数Flags,Android提供了以下几种

DEFAULT 这个参数是默认,使用默认的方法来加密
NO_PADDING 这个参数是略去加密字符串最后的”=”
NO_WRAP 这个参数意思是略去所有的换行符(设置后CRLF就没用了)
CRLF 这个参数看起来比较眼熟,它就是Win风格的换行符,意思就是使用CR LF这一对作为一行的结尾而不是Unix风格的LF
URL_SAFE 这个参数意思是加密时不使用对URL和文件名有特殊意义的字符来作为加密字符,具体就是以-和_取代+和/

Base64使用类

  • 使用sun.misc包下的BASE64Encoder及BASE64Decoder类。这两个类是sun公司的内部方法,并没有在java api中公开过。网上也有相关的这两个类,也许写法不同,但效果一样,可以拷到项目中做工具类使用。

  • Android2.2版本的源代码中提供的android.util包下的Base64类,以上的实现就是采用这个类。(我所采用)

  • 此外网上还有org.apache.commons.codec.binary.Base64类作为替代sun.misc包下的Base64类。

总结

大多数的编码都是由字符转化成二进制的过程,而从二进制转成字符的过程称为解码。而Base64的概念就恰好反了,由二进制转到字符称为编码,由字符到二进制称为解码。
当然,正因为如此,Base64也常常在加解密中使用到,因为加密后字节数组不属于任何字符集,如果字节用StringAPI转换成字符只能得到乱码,这时候就可以利用Base64了,这个在后面的加解密中有更详细的描述。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值