androidbase64加密
1. Android使用RSA加密和解密
1.data是要加密的数据,如果是字符串则getBytes。publicKey是公钥,privateKey是私钥。自定义密钥对测试
2.从文件中读取公钥
当加密的数据过长时,会出现javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes的异常。rsa算法规定一次加密的数据不能超过生成密钥对时的keyLength/8-11,keyLength一般是1024个字节,则加密的数据不能超过117个字节
测试分段加密和解密
生成公钥和私钥后,用base64编码
一、android加密的数据服务器上无法解密?
android的rsa加密方式是RSA/ECB/NoPadding,而标准jdk是RSA/ECB/PKCS1Padding,所以加密时要设置标准jdk的加密方式
二、base64编码。因为不同的设备对字符的处理方式不同,字符有可能处理出错,不利于传输。所以先把数据做base64编码,变成可见字符,减少出错
官方提供的base64类,Base64.encode编码,Base64.decode解码。用这个会有换行符,需要自定义
三、rsa是非对称加密算法。依赖于大数计算,加密速度比des慢,通常只用于加密少量数据或密钥
四、公钥加密比私钥加密块,公钥解密比私钥解密慢。加密后的数据大概是加密前的1.5倍
2. android 怎么用base64 加密imageview
// 加密传入的数据是byte类型的,并非使用decode方法将原始数据转二进制,String类型的数据 使用 str.getBytes()即可
String str = "Hello!";
// 在这里使用的是encode方式,返回的是byte类型加密数据,可使用new String转为String类型
String strBase64 = new String(Base64.encode(str.getBytes(), Base64.DEFAULT));
Log.i("Test", "encode >>>" + strBase64);
// 这里 encodeToString 则直接将返回String类型的加密数据
String enToStr = Base64.encodeToString(str.getBytes(), Base64.DEFAULT);
Log.i("Test", "encodeToString >>> " + enToStr);
Log.i("Test", "decode >>>" + new String(Base64.decode(strBase64.getBytes(), Base64.DEFAULT)));
3. 什么加密方式加密玩密文后只出现两个字母
是Base64的加密方式。Base64加密无论明文是什么(比如汉字,灶裂特殊符号等),加密后的密文都只会变成仿陆字母A-Z、a-z、0-9、加、/这64个字符,被他加密体后积一般会隐大闭变成原来的4/3。
4. Android加密算法总结
1.概念:
Base64是一种用64个字符(+/)来表示二进制数据的方法,只是一种编码方式,所以不建议使用Base64来进行加密数据。
2.由来:
为什么会有Base64编码呢?因为计算机中数据是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。在网络上交换数据时,比如图片二进制流的每个字节不可能全部都是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送,把不可打印的字符也能用可打印字符来表示,所以就先把数据先做一个Base64编码,统统变成可见字符,降低错误率。
3.示例:
加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。
1.DES
DES全称为Data Encryption Standard,即数据加密标准,是一种使用 密钥加密 的块算法。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
2.3DES
3DES(或称为Triple DES)是三重 数据加密算法 (TDEA,Triple Data Encryption Algorithm)块密码的通称。是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。
3.AES
AES全称Advanced Encryption Standard,即高级加密标准,当今最流行的对称加密算法之一,是DES的替代者。支持三种长度的密钥:128位,192位,256位。
AES算法是把明文拆分成一个个独立的明文块,每一个明文块长128bit。这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。
但是这里涉及到一个问题:假如一段明文长度是192bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding):
AES的工作模式,体现在把明文块加密成密文块的处理过程中。
加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。
1.SHA
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法,且若输入的消息不同,它们对应到不同字符串的机率很高。
SHA分为SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512五种算法,后四者有时并称为SHA-2。SHA-1在许多安全协定中广为使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为是MD5(更早之前被广为使用的杂凑函数)的后继者。但SHA-1的安全性如今被密码学家严重质疑;虽然至今尚未出现对SHA-2有效的攻击,它的算法跟SHA-1基本上仍然相似;因此有些人开始发展其他替代的杂凑算法。
2.RSA
RSA算法1978年出现,是第一个既能用于数据加密也能用于数字签名的算法,易于理解和操作。
RSA基于一个数论事实:将两个大素数相乘十分容易,但想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可提供给任何人使用,私钥则为自己所有,供解密之用。
3.MD5
MD5信息摘要算法 (英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值,用于确保信息传输完整一致。具有如下优点:
XOR:异或加密,既将某个字符或者数值 x 与一个数值 m 进行异或运算得到 y ,则再用 y 与 m 进行异或运算就可还原为 x。
使用场景:
(1)两个变量的互换(不借助第三个变量);
(2)数据的简单加密解密。
5. Android在用AES加密字符串之后再用base64加密,加密的结果跟ios端不一样,
之前在项目上用到AES256加密解密算法,刚开始在java端加密解密都没有问题,在iOS端加密解密也没有问题。但是奇怪的是在java端加密后的文件在iOS端无法正确解密打开,然后简单测试了一下,发现在java端和iOS端采用相同明文,相同密钥加密后的密文不一样!上网查了资料后发现iOS中AES加密算法采用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。我们知道加密算法由算法+模式+填充组成,所以这两者不同的填充算法导致相同明文相同密钥加密后出现密文不一致的情况。那么我们需要在java中用PKCS7Padding来填充,这样就可以和iOS端填充算法一致了。
要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现,下面我会提供该包的下载。啰嗦了一大堆,下面是一个简单的测试,上代码!
001 package com.encrypt.file;
002
003
004 import java.io.UnsupportedEncodingException;
005 importjava.security.Key;
006 import java.security.Security;
007
008 importjavax.crypto.Cipher;
009 importjavax.crypto.SecretKey;
010 importjavax.crypto.spec.SecretKeySpec;
011
012 public classAES256Encryption{
013
014 /**
015 * 密钥算法
016 * java6支持56位密钥,bouncycastle支持64位
017 * */
018 public static finalString KEY_ALGORITHM="AES";
019
020 /**
021 * 加密/解密算法/工作模式/填充方式
022 *
023 * JAVA6 支持PKCS5PADDING填充方式
024 * Bouncy castle支持PKCS7Padding填充方式
025 * */
026 public static finalString CIPHER_ALGORITHM="AES/ECB/PKCS7Padding";
027
028 /**
029 *
030 * 生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥
031 * @return byte[] 二进制密钥
032 * */
033 public static byte[] initkey() throwsException{
034
035 // //实例化密钥生成器
036 // Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
037 // KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
038 // //初始化密钥生成器,AES要求密钥长度为128位、192位、256位
039 //// kg.init(256);
040 // kg.init(128);
041 // //生成密钥
042 // SecretKey secretKey=kg.generateKey();
043 // //获取二进制密钥编码形式
044 // return secretKey.getEncoded();
045 //为了便于测试,这里我把key写死了,如果大家需要自动生成,可用上面注释掉的代码
046 return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,
047 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f,
048 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09,
049 0x06, 0x07, 0x09, 0x0d };
050 }
051
052 /**
053 * 转换密钥
054 * @param key 二进制密钥
055 * @return Key 密钥
056 * */
057 public static Key toKey(byte[] key) throwsException{
058 //实例化DES密钥
059 //生成密钥
060 SecretKey secretKey=newSecretKeySpec(key,KEY_ALGORITHM);
061 returnsecretKey;
062 }
063
064 /**
065 * 加密数据
066 * @param data 待加密数据
067 * @param key 密钥
068 * @return byte[] 加密后的数据
069 * */
070 public static byte[] encrypt(byte[] data,byte[] key) throwsException{
071 //还原密钥
072 Key k=toKey(key);
073 /**
074 * 实例化
075 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
076 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
077 */
078 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
079 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");
080 //初始化,设置为加密模式
081 cipher.init(Cipher.ENCRYPT_MODE, k);
082 //执行操作
083 returncipher.doFinal(data);
084 }
085 /**
086 * 解密数据
087 * @param data 待解密数据
088 * @param key 密钥
089 * @return byte[] 解密后的数据
090 * */
091 public static byte[] decrypt(byte[] data,byte[] key) throwsException{
092 //欢迎密钥
093 Key k =toKey(key);
094 /**
095 * 实例化
096 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
097 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
098 */
099 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
100 //初始化,设置为解密模式
101 cipher.init(Cipher.DECRYPT_MODE, k);
102 //执行操作
103 returncipher.doFinal(data);
104 }
105 /**
106 * @param args
107 * @throws UnsupportedEncodingException
108 * @throws Exception
109 */
110 public static void main(String[] args) {
111
112 String str="AES";
113 System.out.println("原文:"+str);
114
115 //初始化密钥
116 byte[] key;
117 try {
118 key = AES256Encryption.initkey();
119 System.out.print("密钥:");
120 for(int i = 0;i<key.length;i++){
121 System.out.printf("%x", key[i]);
122 }
123 System.out.print("\n");
124 //加密数据
125 byte[] data=AES256Encryption.encrypt(str.getBytes(), key);
126 System.out.print("加密后:");
127 for(int i = 0;i<data.length;i++){
128 System.out.printf("%x", data[i]);
129 }
130 System.out.print("\n");
131
132 //解密数据
133 data=AES256Encryption.decrypt(data, key);
134 System.out.println("解密后:"+newString(data));
135 } catch (Exception e) {
136 // TODO Auto-generated catch block
137 e.printStackTrace();
138 }
139
140 }
141 }
运行程序后的结果截图:
ViewController.m文件
01 //
02 // ViewController.m
03 // AES256EncryptionDemo
04 //
05 // Created by 孙 裔 on 12-12-13.
06 // Copyright (c) 2012年 rich sun. All rights reserved.
07 //
08
09 #import "ViewController.h"
10 #import "EncryptAndDecrypt.h"
11
12 @interface ViewController ()
13
14 @end
15
16 @implementation ViewController
17 @synthesize plainTextField;
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21 // Do any additional setup after loading the view, typically from a nib.
22 }
23
24 - (void)didReceiveMemoryWarning
25 {
26 [super didReceiveMemoryWarning];
27 // Dispose of any resources that can be recreated.
28 }
29 //这个函数实现了用户输入完后点击视图背景,关闭键盘
30 - (IBAction)backgroundTap:(id)sender{
31 [plainTextField resignFirstResponder];
32 }
33
34 - (IBAction)encrypt:(id)sender {
35
36 NSString *plainText = plainTextField.text;//明文
37 NSData *plainTextData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
38
39 //为了测试,这里先把密钥写死
40 Byte keyByte[] = {0x08,0x08,0x04,0x0b,0x02,0x0f,0x0b,0x0c,0x01,0x03,0x09,0x07,0x0c,0x03,
41 0x07,0x0a,0x04,0x0f,0x06,0x0f,0x0e,0x09,0x05,0x01,0x0a,0x0a,0x01,0x09,
42 0x06,0x07,0x09,0x0d};
43 //byte转换为NSData类型,以便下边加密方法的调用
44 NSData *keyData = [[NSData alloc] initWithBytes:keyByte length:32];
45 //
46 NSData *cipherTextData = [plainTextData AES256EncryptWithKey:keyData];
47 Byte *plainTextByte = (Byte *)[cipherTextData bytes];
48 for(int i=0;i<[cipherTextData length];i++){
49 printf("%x",plainTextByte[i]);
50 }
51
52 }
53 @end
6. base64是一种高强度的加密算法是不可破解的对吗
Base64不是加密算法,它仅仅是一种编码方式,算法也是公开的,所以不能依赖兄桐它进行加密。Base64是一种编悄贺码羡运坦方式,不是加密算法,它是没有可读性的,但不代表这个编码就是加密的。加密需要保证没有秘钥的人无法解密信息,更无法从密文中破解任务明文信息,但Base64可以很轻松的反编码。另外它没有用到秘钥 不具有加密算法的安全性。
7. android,java 通用的加密解密方式有几种
移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如.NET和android或者iOS的打交道。为了让数据交互更安全,我们需要对数据进行加密传输。今天研究了一下,把几种语言的加密都实践了一遍,实现了.NET,java(android),iOS都同一套的加密算法,下面就分享给大家。
AES加密有多种算法模式,下面提供两套模式的可用源码。
加密方式:
先将文本AES加密
返回Base64转码
解密方式:
将数据进行Base64解码
进行AES解密
一、CBC(Cipher Block Chaining,加密块链)模式
是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度.
密钥
密钥偏移量
java/adroid加密AESOperator类:
package com.bci.wx.base.util;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* AES 是一种可逆加密算法,对用户的敏感信息加密处理 对原始数据进行AES加密后,在进行Base64编码转化;
*/
public class AESOperator {
/*
* 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式,key需要为16位。
*/
private String sKey = "smkldospdosldaaa";//key,可自行修改
private String ivParameter = "0392039203920300";//偏移量,可自行修改
private static AESOperator instance = null;
private AESOperator() {
}
public static AESOperator getInstance() {
if (instance == null)
instance = new AESOperator();
return instance;
}
public static String Encrypt(String encData ,String secretKey,String vector) throws Exception {
if(secretKey == null) {
return null;
}
if(secretKey.length() != 16) {
return null;
}
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] raw = secretKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(vector.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(encData.getBytes("utf-8"));
return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
}
// 加密
public String encrypt(String sSrc) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] raw = sKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
}
// 解密
public String decrypt(String sSrc) throws Exception {
try {
byte[] raw = sKey.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "utf-8");
return originalString;
} catch (Exception ex) {
return null;
}
}
public String decrypt(String sSrc,String key,String ivs) throws Exception {
try {
byte[] raw = key.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "utf-8");
return originalString;
} catch (Exception ex) {
return null;
}
}
public static String encodeBytes(byte[] bytes) {
StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
}
return strBuf.toString();
}
8. 谈一谈Android的签名机制
首先,签名是防止apk信息被修改的一个机制,打包时把apk的信息与证书做处理,生成加密信息,安装时发现问题则拒绝安装
v1签名将apk的其他文件与证书做处理,信息保存到META-INF文件夹里,这么做的主要问题是直接修改apk包体是没法检测出来的,并由此导致了如Janus(CVE-2017-13156)这样的极严重的漏洞(ART支持直接运行dex文件,通过dex头部的魔数进行判断,而应用安装过程中是通过zip尾部的魔数判断是否是有效的zip文件,所以只要构造出一个既是dex又是zip的文件就能绕过签名验证修改里面的dex文件)
v2签名则直接用apk文件,处理之后写入进去,这样修改包体也会被系统检测出从而被拒绝安装.
v1签名:将apk中文件加密保存到META-INF目录中,不包含META-INF目中的文件。生成MANIFEST.MF、CERT.SF、CERT.RSA文件
MANIFEST.MF :保存各文件的SHA-1通过BASE64加密后的值
CERT.SF:保存MANIFEST.MF文件的SHA-1通过Base64加密后的值 和MANIFEST.MF中各项的值再次SHA-1并Base64加密保存
CERT.RSA:保存公钥和发布机构信息
v2签名:对apk整个文件进行分块摘要加密,并把加密信息存在zip中央目录前 放在apk sign block区
Android 7.0中引入了APK Signature Scheme v2,v1是jar Signature来自JDK。
V1:应该是通过ZIP条目进行验证,这样APK 签署后可进行许多修改 - 可以移动甚至重新压缩文件。
V2:验证压缩文件的所有字节,而不是单个 ZIP 条目,因此,在签名后无法再更改(包括 zipalign)。正因如此,现在在编译过程中,我们将压缩、调整和签署合并成一步完成。好处显而易见,更安全而且新的签名可缩短在设备上进行验证的时间(不需要费时地解压缩然后验证),从而加快应用安装速度。
v1和v2的签名使用
1)只勾选v1签名并不会影响什么,但是在7.0上不会使用更安全的验证方式
2)只勾选V2签名7.0以下会直接安装完显示未安装,7.0以上则使用了V2的方式验证
3)同时勾选V1和V2则所有机型都没问题
9. Android Okhttp/Retrofit网络请求加解密实现方案
比较安全的方案应该是AES+RSA的加密方式。具体如下图所示。
为什么要这样做呢?
1、RSA是非对称加密,公钥和私钥分开,且公钥可以公开,很适合网络数据传输场景。但RSA加密比较慢,据说比AES慢100倍,且对加密的数据长度也有限制。
2、AES是对称加密,加密速度快,安全性高,但密钥的保存是个问题,在网络数据传输的场景就很容易由于密钥泄露造成安全隐患
3、所以,AES+RSA结合才更好,AES加密数据,且密钥随机生成,RSA用对方(服务器)的公钥加密随机生成的AES密钥。传输时要把密文,加密的AES密钥和自己的公钥传给对方(服务器)。对方(服务器)接到数据后,用自己的私钥解密AES密钥,再拿AES密钥解密数据得到明文。这样就综合了两种加密体系的优点。
4、除上面说的外,还可以加签名,即对传输的数据(加密前)先做个哈希,然后用自己的RSA私钥对哈希签名(对方拿到自己的公钥可以验签),这样可以验证传输内容有没有被修改过。
就java来说,加密的输入和输出都是字节数组类型的,也就是二进制数据,网络传输或本地保存都需要重新编码为字符串。推荐使用Base64。Android 有自带的Base64实现,flag要选Base64.NO_WRAP,不然末尾会有换行影响服务端解码。
Android中Base64加密
总而言之,这些不同语言都有实现库,调用即可,关键是参数要一致,具体还需要和后台联调一下。
rsa加解密的内容超长的问题解决
现在说到网络框架,应该毫无疑问是Retrofit了。上面说的加密方案说到底还是要在网络请求框架内加上,怎么做入侵最小,怎么做最方便才是重点。
1、坑定不能直接在接口调用层做加密,加参数,这样每个接口都要修改,这是不可能的。
2、ConverterFactory处理,这也是网上可以搜到的很多文章的写法,但我觉得还是有入侵。而且有点麻烦。
3、OkHttp添加拦截器,这种方法入侵最小(可以说没有),实现呢也非常优雅。
下面的实现,网上也找不到多少可以参考的文章,但不得不说,OkHttp的封装和设计真的很好用,所见即所得。看下源码,就知道该怎么用了,连文档都不用查。
主要注意点:
0、和接口无关的新加的数据放在请求头里。
1、该close的要close,不然会内存泄漏。
2、新旧Request和Response要区分好,新的要替换旧的去传递或返回。
3、要对response.code()做处理,只有在和后台约定好的返回码下才走解密的逻辑,具体看自己的需求,不一定都是200。
10. Base64编码是加密算法吗
大家好,我是阿萨。昨天和开发同学一起开会的时候。开发同学说到了用Base64编码,我立即说 不能使用Base64加密。然后开发来了一句Base64不是加密算法。当时懵了。默默记下这个知识点,回来学习下。
先给大家讲解下我为什么会有不能使用Base64加密的意识。很多年前,我遇到的第一个安全问题,就是敏感数据用Base64加密了。 事情起因是,我们接到一个bug,说有个敏感字段使用Base64在前端加密了,然后传给后端了。
基于之前的小故事,对于使用了Base64编码的地方就觉得不安全。这也是为什么会对开发说不能用Base64加密了,
今天我们就来学习下Base64编码。
一,Base64编码的由来。
传说,最开始互联网电子邮件都是英文的,后来互联网传到中国后,互联网电子邮件汉字就不认识了。所以就有了Base64编码,把中文变成可识别的英文。然后Base64编码被广泛用到各行各业。
以上只是传说。真实的由来,就不得而知了。
下面我们从计算机的底层传输过程中。它分为可见字符和不可见字符。可见字符比如我们熟知的ASCII码。
还有一些不可见的控制字符(0~31以及127),比如回车,换行等以及一些二进制数据都是不可见字符。
这些不可见字符在一些硬件,比如交换机,路由器以及网关等识别或者解析错误,导致错误发生,所以就有了Base64编码的市场。因此Base64产生了。
二,Base64 编码的原理
Base64编码就是要把不可见的字符转换成常见的64个字符的过程。
这64个字符是哪些呢?
那么它工作原理是啥呢?
1) 首先把整段传输内容全部划分成三个字节一组。这里就有了24bit了.
2) 然后把24bit 分成四组。每一组就有6bit
3)在6bit的最前面添加2个0,这样就有了8bit
4)把这8bit 转换成一个字节。查找上表中对应字符。所有其他分组内容按照这样的处理逻辑处理下。就得到了Base64的编码后字符。
注意,如果不够三字节,用0填到三字节,同时补充了多少个字节的0,末尾就添加就几个=。
分别图示下以上过程:
三个A
2个A,补充一个0
1个A,补充2个0
三,总结
Base64编码不是用来加密的,也不是加密算法。它只是用来编码的。切记不可用于加密。如果敏感信息用Base64编码加密了,赶紧提bug。
经过今天的学习,希望大家有所收获。
如果你喜欢今天的内容,欢迎点赞,关注。