密码学:一文看懂Base64算法

请添加图片描述

前言

Base64常常在我们开发中出现,我们可能只知道它是一串乱码(看不懂的符号),知道有时候知道我们需要把一些数据进行base64编码,有时候需要进行Base64解码。但是却不知道它的作用是什么?它存在的意义是什么?还有它是如何生成的?如何编码和解码?
上述的疑问相信在你读完本篇文章之后烟消云散。

下面开始正文。

什么是Base64?

Base64是什么?
它和加密解密操作有什么关系吗?
让我们先来看看以下这段看似诡异的乱码:

54K55Liq5YWz5rOo77yM5piv5a+55oiR5oyB57ut5Yib5L2c55qE5pyA5aSn55qE6byT5Yqx77yB

没错,这就是经过Base64编码后的字符串。对它解码后,我们获得以下内容

点个关注,是对我持续创作的最大的鼓励!

这段文字在经过Base64编码后面目全非,而经过Base64解码后又能恢复本来面目,这很有加密解密的意味。不过Base64算法并不是加密算法,仅仅是加密算法的近亲。Base64算法的转换方式很像古典加密算法中的单表置换算法。下面来介绍这种常用于电子邮件的算法。

Base64算法的由来

Base64算法最早应用于解决电子邮件传输的问题。在早期,由于 “历史问题” 电子邮件只允许ASCII码字符。如果要传输一封带有非ASCII码字符的电子邮件,当它通过有 “历史问题” 的网关时就可能出现问题。这个网关很可能会对这个非ASCII码字符的二进制位做调整,即将这个非ASCII码的8位二进制码的最高位置为0。此时用户收到的邮件就会是一封纯粹的乱码邮件了。基于这个原因产生了Base64算法。
对ASCII码概念感觉模糊的同学可以去看看这篇文章:一文看懂所有字符编码标准

Base64算法的定义

Base64是一种基于64个 字符的编码算法,根据RFC2045的定义:“Base64内容传送编码是一种以任意8位字节序列组合的描述形式,这种形式不易被人直接识别”。

经过Base64编码后的数据会比原始数据略长,为原来的4/3倍。

经Base64编码后的字符串的字符数是以4为单位的整数倍。

RFC2045还规定,在电子邮件中,每行为76个字符,每行末需添加一个回车换行符(“\r\n”),不论每行是否够76个字符,都要添加一个回车换行符。但在实际应用中,往往根据实际需要忽略了这一要求。
在RFC2045文件中给出了如下字符映射表:

在这里插入图片描述
这张字符映射表中,Value指的是十进制编码,Encoding指的是字符,共映射了64个字符,这也是Base64算法命名的由来。映射表的最后一个字符是等号,它是用来补位的。有经验的朋友一看到字符串末尾有个等号,就会联想到Base64算法了。
其实,Base64算法还有几个同胞兄弟,如Base32和Base16算法。为了能在http请求中以Get方式传递二进制数据,由Base64算法衍生出了Url Base64算法。

Url Base64算法主要是替换了Base64 字符映射表中的第62和63个字符,也就是将“+”和“/”符号替换成了“-”和“_”符号。但对于补位符“=”,一种建议是使用"~ "符号,另一种建议是使用“.”符号。其中,由于“~”符号与文件系统冲突,不建议使用。

而对于“.”符号,如果出现连续两次,则认为是错误。对于补位符的问题,Bouncy Castle和Commons Codec有差别,Bouncy Castle使用"."作为补位符,而Commons Codec则完全杜绝使用补位符。

有关Base16、Base32和Url Base64算法的详细内容,可以参考RFC4648

Base64算法与加密算法的关系

Base64算法有编码和解码操作可充当加密和解密操作,还有一张字符映射表充当了密钥。

单表置换算法,Base64算法正是运用了这一思想,将原文经二进制转换后与字符映射表相对应,得到“密文”。Base64算法经常用做一个简单的“加密”来保护某些数据。

尽管如此,Base64算法仍不能叫做加密算法。Base64算法公开,这一点与柯克霍夫原则并无违背,但充当密钥的字符映射表公开,直接违反了柯克霍夫原则,而且Base64算法的加密强度并不够高。因此,不能将Base64算法看做我们所认可的现代加密算法。

Base64算法虽不能称为加密算法,但其变换法则遵从了单表置换算法。也正因如此,Base64算法成为加密算法学习最好的范例。尤其是在自定义加密算法研制方面,Base64算法是一个很不错的参考。如果我们将Base64算法做少许改造,并将字符映射表调整、保密,改造后的Base64算法就具备了加密算法的意义!除此之外,Base64算法常作为密钥、密文和证书的一种通用存储编码格式,与加密算法形影不离。

实现原理

Base64算法主要是将给定的字符以与字符编码(如ASCII码,UTF-8码)对应的十进制数为基准,做编码操作:
1)将给定的字符串以字符为单位,转换为对应的字符编码 (如ASCII码)
2)将获得的字符编码转换为二进制码
3)对获得的二进制码做分组转换操作,每3个8位二进制码为一组,转换为每4个6位二进制码为一组(不足6位时低位补0) 。这是一个分组变化的过程,3个8位二进制码和4个6位二进制码的长度都是24位(3x8=4x6=24)
4)对获得的4-6二进制码补位,向6位二进制码添加2位高位0,组成4个8位二进制码。
5)将获得的4-8二进制码转换为十进制码
6)将获得的十进制码转换为Base64字符表中对应的字符

我们对字符串“A”进行Base64编码:

字符             A
ASCII码          65
二进制码         01000001
4-6二进制码      010000       010000
4-8二进制码      00010000     00010000
十进制码         16           16
字符表映射码      Q            Q           =   =

由此,字符串“A”经过Base64编码后就得到了“QQ==”这样一个字符串。

Base64解码操作就是编码操作的逆运算,反推上述流程很容易获得原文信息。

"A"经过Base64编码后的字符串末尾带着2个等号。很显然,当原文的二进制码长度不足24位,最终转换为十进制码时也不足4项,这时就需要用等号补位。如果原文只有一个字符,那么经过Base64编码后的字符串末尾会有2个等号。
经Base64编码后的字符串最多只会有2个等号,这是因为:

余数 = 原文字节数 MOD 3

这是一个简单的算术问题,余数的值只可能是0、1或2。

余数为0时,则原文字节数恰好是3的倍数,没有等号。

这个尾巴;余数为1时,则为了让Base64编码后的字符数是4的倍数,要补2个等号。

同理,余数为2时,则要补1个等号。

所以,通常判别一个字符串是不是Base64编码的第一步操作就是判断这个字符串末尾是不是有等号。

这同时也说明,Base64编码后的字符串是以4个字符为单位,其长度只能是4个字符的整数倍。

本文开篇对“点个关注,是对我持续创作的最大的鼓励!”这个字符串做了Base64编码后获 得了一个长度为 76个字符的字符串“54K55Liq5YWz5rOo77yM5piv5a+55oiR5oyB57ut5Yib5L2c55qE5pyA5aSn55qE6byT5Yqx77yB”,正好说明了这一点。

非ASCII码字符编码

Base64算法很好地解决了非ASCII码字符的传输问题,譬如中文字符的传输问题。
ASCII码可以表示十进制范围为0~ 127的字符,对应二进制范围是00000000~01111111。ASCII码包括阿拉伯数字、大小写英文字母和一些控制符,但却没有包含双字节编码的字符,如中文字符。因此有了GB2312、GBK和UTF-8等编码。GB2312、GBK用2个字节表示一个汉字,UTF-8编码则用3个字节表示一个汉字。Base64算法实现时,对6位二进制码添加高2位0,恰恰保护了非ASCII码字符在通过有问题的网关时不发生问题。

我们以字符串“密”为例,字符串“密“对应的UTF-8编 码就是-27,-81,-122。我们对其做如下Base64编码:

字符               密
UTF-8码            -27           -81            -122
二进制码           11100101      10101111       10000110
4-6二进制码        111001        011010         111110         000110
4-8二进制码        00111001      00011010       00111110       00000110
十进制码           57            26             62             6
字符表映射码       5             a              +              G

字符串“密”经过Base64编码后得到字符串“5a+G”。

传递模型

在这里插入图片描述
我们通过时序图来描述一次基于Base64算法的消息传递。这里,我们仍以甲方与乙方交互数据举例。甲方作为数据的发送方,乙方作为数据的接收方。其操作流程如下:
1)甲方对数据做Base64编码处理
2)甲方将编码后的数据发送给乙方
3)乙方获得数据后对数据做Base64解码处理
要操作Base64算法并不复杂。甲乙双方可以通过上述流程完成一次数据通信,或是单方面地进行电子邮件发送,亦或是仅仅为了传输非ASCII码的字符信息等。

这些操作在实际应用中常常是通过Base64算法来完成的。

应用场景

Base64算法广泛应用于电子邮件传输,以及密钥和证书文件的文本方式保存。在数据保密要求强度不高的情况下,可以使用Base64算法做简单的数据“加密”。

电子邮件传输

电子邮件一般都会使用Base64算法,我们截取一段电子邮件信息:

Content-Type: text/plain;
charset="utf8"
Content-Transfer-Encoding: base64
6L+Z5piv5LiA5bCB5rWL6K+V6YKu5Lu277yB

在这封邮件里,我们看到了我们需要的信息

  • 字符集编码: charset charset="utf8
  • 内容传输编码: Content-Transfer-Encoding:base64
  • 邮件内容: 6L+Z5piv5LiA5bCB5rWL6K+V6YKu5Lu277yB

通过上述信息,我们确定无疑这是一封使用了Base64编码的邮件,并且邮件的内容使用的是UTF-8编码的字符集。由此,我们只需要通过上述Base64算法的实现类一Base64Coder完成解码操作。毋庸置疑,这份邮件的内容是:“这是一封测试邮件!“

网络数据传输

不论是通过HTTP的Get方式以URL参数传输数据,还是通过Post方式以数据体传输数据,都能发现Base64编码藏匿其中
只要通信双方在通信前约定好字符编码和字符映射表,改良后的Base64算法就可以在HTTP环境中以Get/Post方式传递二进制数据。这时的Base64算法,无疑成为了一种简单的加密算法。

密钥存储

在计算机的世界里,密钥就是一段二进制的数据。
密钥的二进制表现形式使得它的安全性大为提升,但却大大降低了它的可读性。通常我们希望密钥可以有一个容易理解的表现形式(如经过Base64编码后的字符串),以增强它的可读性并且方便密钥的发放。如甲方向乙方发送密钥,可以将密钥以二进制形式转化为Base64编码后的字符串形式,通过安全途径以文档形式发放给乙方,密钥很可能被要求写在合同中。
Base64算法的优势恰恰是在基于二进制编码格式的转换上,这一点使得二进制的密钥通常以Base64编码的形式展现。

另一种类似的效果是将二进制串转为十六讲制串,如消息摘要结果。以下是一个经过Base64编码处理后DES的密钥:

I6ttWOmtSo8=

这样处理后的密钥看起来就比较容易接受,可以将其放到合同书中,发放给其他人。

数字证书

数字证书可以使用多种格式存储,常见的包括:

  1. X.509 PEM 格式:
    X.509 PEM 格式是一种常见的证书格式,通常使用Base64编码,以ASCII文本的形式存储。PEM文件通常以.pem.crt.cer.key等扩展名结尾。

PEM 格式证书通常如下:
-----BEGIN CERTIFICATE----- MIIFqzCCBJOgAwIBAgIQAf2jJAY75k6nqYDL5OwZpzANBgkqhkiG9w0BAQwFADB5 [...] u+Dvi9IJOZd/21Bbsb/6bER5epqCyl/wI -----END CERTIFICATE-----

  1. DER 格式:
    DER(Distinguished Encoding Rules)格式是二进制编码的 X.509 证书格式,通常以.der.cer.crt等扩展名结尾。

  2. PKCS#12 格式(PFX 或 P12):
    PKCS#12 是一种可包含公钥、私钥和证书链等信息的存储格式。通常以.p12.pfx等扩展名结尾。

  3. JKS 格式:
    JKS(Java KeyStore)是Java中常见的密钥存储格式,可以用于存储证书和密钥。通常以.jks扩展名结尾。

  4. PKCS#7 / P7B 格式:
    PKCS#7 或 P7B 格式用于存储证书链,通常以.p7b.p7c等扩展名结尾。

  5. CAdES 格式:
    CAdES(CMS Advanced Electronic Signatures)是用于电子签名的一种格式,扩展了 CMS(Cryptographic Message Syntax)。通常以.p7m.p7s等扩展名结尾。

参考

《Java加密与解密艺术》

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《应用密码学:协议、算法与C源程序》是一本关于密码学的重要著作。该书主要介绍了密码学的基本概念、协议和算法以及相关的C语言源代码。 在协议方面,该书详细介绍了一些常见的密码学协议,如RSA、Diffie-Hellman、AES等。这些协议是实现安全通信和数据保护的基础,读者可以通过学习这些协议了解到密码学在实际应用中的工作原理。 在算法方面,该书涵盖了密码学中一些经典的算法,如对称加密算法、非对称加密算法和哈希算法等。对称加密算法包括DES、AES等,非对称加密算法包括RSA等,而哈希算法包括MD5、SHA-1等。这些算法的原理和实现细节都在书中有详细的介绍,读者可以通过学习这些算法了解到密码学在保护数据传输和存储安全方面的作用。 同时,该书还提供了一些相关的C语言源代码示例,以便读者更好地理解协议和算法的实现过程。这些源代码可以帮助读者理解密码学在实际编程中的应用方式,有助于读者在自己的项目中使用密码学技术实现安全保护。 总之,《应用密码学:协议、算法与C源程序》是一本涵盖了密码学基本概念、协议、算法和源代码的综合性教材,对于想要深入了解密码学并应用到实际项目中的读者来说是一本不可多得的书籍。 ### 回答2: 《应用密码学:协议、算法与C源程序》是一本关于密码学领域的书籍,主要介绍密码学在通信安全和数据保护方面的应用。通过该书,读者可以深入了解密码学的理论基础、常用协议、算法和C语言实现。下面我将简要介绍一些书籍内容。 首先,该书详细介绍了密码学的基本概念和原理。读者可以了解加密算法、解密算法、对称加密和非对称加密等密码学基础知识,理解信息的加密和解密过程。 其次,该书介绍了一些常用的密码协议,如SSL/TLS协议、IPSec协议等。读者可以了解这些协议的原理、安全性和应用场景,深入了解网络通信安全中密码学的应用。 此外,该书还详细介绍了一些常见的密码算法,如DES、AES、RSA等。读者可以学习这些算法的原理、加密过程和解密过程,并且提供了相应的C语言源代码供读者进行实践。这有助于读者进一步理解密码算法的具体实现和应用。 最后,该书还介绍了一些密码学中的实际应用,如数字签名、数字证书、身份认证等。读者可以了解这些应用的原理和实现方式,进一步了解密码学在实际场景中的应用价值。 总之,《应用密码学:协议、算法与C源程序》是一本很好的密码学领域的入门书籍,通过学习该书可以深入了解密码学的基本原理、常用协议和算法,并且提供了相关的C语言源代码供读者实践。无论是对于密码学专业人士还是对于对密码学有兴趣的读者,这本书都是一本值得推荐的参考书。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林树杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值