Java 常用数据编码以及加密解密算法
Java 常用数据编码以及加密解密算法
概要
加密算法是一种用数学方法对数据进行变换的技术,目的是保护数据的安全,防止被未经授权的人读取或修改。加密算法可以分为三大类:对称加密算法、非对称加密算法和哈希算法(也叫摘要算法)。
本文来梳理下开发中常用到的数据编码中的Base64以及常见的一些加密算法。
一、数据编码
1. Base64 算法
Base64编码本质上是一种将二进制数据转成文本数据的方案。对于非二进制数据,是先将其转换成二进制形式,每 3 个字节(3 × 8 = 24 位)数据被分成 4 组,每组 6 位。然后每连续6bit(2的6次方=64)计算其十进制值,根据该值在A-Z,a-z,0-9,+,/ 这64个字符中找到对应的字符,最终得到一个文本字符串。每个 Base64 编码字符对应一个 ASCII 字符。
注意填充:如果输入的字节数不是 3 的倍数,会使用 “=” 填充,使最终的编码长度是 4 的倍数(单位:字符)。
1)可读性编码算法
Base64算法并不是加密算法,它的出现是为了解决ASCII码在传输过程中可能出现乱码的问题。Base64是网络上最常见的用于传输8bit字节码的可读性编码算法之一。可读性编码算法不是为了保护数据的安全性,而是为了可读性。可读性编码不改变信息内容,只改变信息内容的表现形式。
2)64种字符
Base64使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/”,故得此名。
Base64编码对照表:
2. URL Base64算法
UrlBase64 是 Base64 编码的一种变体,主要用于在 URL 中安全地传输二进制数据。它与标准的 Base64 编码相比,有一些微小的差异,以确保编码后的字符在 URL 中不会引起问题。
UrlBase64 主要有以下两个特点:
1)字符集不同:在标准的 Base64 编码中,使用字符 "+", "/",而这两个字符在 URL 中有特殊的含义,可能会引起歧义或导致 URL 解析错误。为了解决这个问题,UrlBase64 将字符 "+" 替换为 "-", 将 "/" 替换为 "_"。
2)去掉填充字符: 标准的 Base64 编码在最后可能会使用一个或两个 "=" 字符进行填充,以使编码后的字符串长度是4的倍数。但是在 URL 中,这些填充字符可能引起问题,因此 UrlBase64 通常去掉填充字符,直接使用编码后的字符串。
总体而言,UrlBase64 是为了适应 URL 中的特殊需求而修改的 Base64 编码。在处理需要在 URL 中传递的二进制数据时,使用 UrlBase64 可以确保编码后的字符串在 URL 中是安全且可靠的。在使用 UrlBase64 解码时,需要在解码之前将 "_" 替换为 "/",将 "-" 替换为 "+",并根据需要删除填充字符。
二、哈希算法
哈希算法也叫散列函数或摘要算法,它的作用是将任意长度的数据映射为固定长度的值的算法,通常这个映射值称为哈希值(Hash Value)或者散列值或者消息摘要。
1. 不属于加密算法
哈希算法其实不属于加密算法,只是可以用到某些加密场景中(例如密码加密),两者可以看作是并列关系。加密算法通常指的是可以将明文转换为密文,并且能够通过某种方式(如密钥)再将密文还原为明文的算法。而哈希算法是一种单向过程,它将输入信息转换成一个固定长度的哈希值,但这个过程是不可逆的,也就是说,不能从哈希值还原出原始信息。
例如:哈希函数 SHA-256 会将任意长度的输入数据映射为一个固定长度的输出(256 位),但无法通过输出值反推出输入数据。
2. 验证数据完整性
相同的内容用同样的摘要算法获得的散列值是一样的,所以常用于验证数据的完整性和一致性。
说明:原始数据的任何改变都会导致哈希值的巨大变化。
3. 哈希算法分类
主要分为三大类:MD(Message Digest,消息摘要算法)、SHA(Secure HashAlgorithm,安全散列算法)和MAC(Message Authentication Code,消息认证码算法)
常见的散列算法:
1)MD(Message Digest,消息摘要算法)
MD2、MD4、MD5 等,已经不被推荐使用。
2)SHA(Secure Hash Algorithm,安全哈希算法)
SHA-1 系列安全性低,SHA2(SHA-224、SHA-256、SHA-384、SHA-512)、SHA3 系列安全性较高。抗碰撞性和抗篡改性显著提升。
SHA-256 是最常用的,它提供了良好的安全性,并且计算效率适中,广泛用于区块链技术(例如比特币)和数字签名等场景。
说明:MD 和 SHA 都是无密钥的纯哈希算法,用于数据完整性校验。
3)Bcrypt(密码哈希算法)
基于 Blowfish 加密算法的密码哈希算法,专门为密码加密而设计,安全性高,属于慢哈希算法。
4)MAC(Message Authentication Code,消息认证码算法)
MAC是结合密钥的哈希算法,增加了消息认证能力(消息是否在传输过程中被篡改,以及确保消息是由合法的发送方发出的)。
HMAC 是一种利用哈希函数生成消息认证码(MAC)的机制:
- 引入密钥增强安全性。
- 可以结合任意安全哈希算法(如 SHA-256)。比如:在 JWT(JSON Web Token)中,HMAC 是常用的签名算法(如 HMAC-SHA256,简称HS256)。
- 主要用于验证数据完整性和消息认证。
5)CRC:(Cyclic Redundancy Check,循环冗余校验)
CRC算法是一种哈希算法,用于生成一个固定长度的值来表示数据的“指纹”。它基于多项式除法的原理,用于检查数据的完整性。
CRC32 是一种 CRC 算法,它的特点是生成 32 位的校验值,通常用于数据完整性校验、文件校验等场景。
应用场景:在 Redis 中,通常通过 CRC16(key) & 16383 来得到哈希槽的位置。CRC16 算法生成的哈希值通常为 16 位。
说明:CRC16 在处理较小的数据集时,冲突概率较低,虽然相比更强大的哈希算法(如 SHA 或 MD5)可能有一些碰撞的风险,但在 Redis 集群的应用场景中,CRC16 仍然足够满足高效、快速的数据分配
5. 加密哈希算法和非加密哈希算法
哈希算法本身不涉及加密/解密操作。根据它们的用途和设计目标进行区分,可以简单分为:
1)加密哈希算法:安全性较高的哈希算法,它可以提供一定的数据完整性保护和数据防篡改能力,能够抵御一定的攻击手段,安全性相对较高,但性能较差,适用于对安全性要求较高的场景。例如 SHA2、SHA3、SM3、RIPEMD-160、BLAKE2、SipHash 等等。
2)非加密哈希算法:安全性相对较低的哈希算法,易受到暴力破解、冲突攻击等攻击手段的影响,但性能较高,适用于对安全性没有要求的业务场景。例如 CRC32、MurMurHash3、SipHash 等等。
说明:在常用的签名算法中,哈希算法本身并不是签名的独立算法,它通常是作为组成部分(数据摘要)与 HMAC、RSA、ECDSA 等加密算法结合使用的。
6. 盐值
盐值通常用于哈希算法中,特别是在密码存储中,以增强哈希计算的安全性。盐值的目的主要是防止彩虹表攻击和暴力破解。盐值是一个随机生成的字符串,它会与原始数据(如密码)一起参与哈希计算,从而使得同样的原始数据每次计算出的哈希值都不相同。
举个例子:
1 // 将密码与盐值结合进行哈希计算 2 public static String hashPassword(String password, byte[] salt) throws Exception { 3 MessageDigest md = MessageDigest.getInstance("SHA-256"); 4 md.update(salt); // 加入盐值 5 byte[] hashedBytes = md.digest(password.getBytes()); 6 return Base64.getEncoder().encodeToString(hashedBytes); 7 }
三、对称加密算法
对称加密算法加密和解密使用的是同一份秘钥,解密是加密的逆运算。对称加密算法加密速度快,密文可逆,一旦秘钥文件泄露,就会导致原始数据暴露。对称加密的结果一般使用Base64算法编码,便于阅读和传输。JDK8支持的对称加密算法主要有DES、DESede、AES、Blowfish,以及RC2和RC4等。不同的算法秘钥长度不同,秘钥长度越长,加密安全性越高。
1. DES算法
DES(Data Encryption Standard,数据加密标准)算法是对称加密算法领域中的典型算法,DES算法秘钥较短,以现在计算机的计算能力,DES算法加密的数据在24小时内可能被破解。所以DES算法已经被淘汰,建议使用AES算法,不过这里还是简单了解下。
2. DESede算法(3DES)
作为DES算法的一种改良,DESede算法(也称为3DES,三重DES)针对其秘钥长度偏短和迭代次数偏少等问题做了相应改进,提高了安全强度,但同时也造成处理速度较慢、秘钥计算时间加长、加密效率不高的问题。所以这里还是简单了解下,实际还是推荐用AES。
3. AES算法
AES(AdvancedEncryption Standard,高级数据加密标准)算法支持128位、192位和256位的秘钥长度,加密速度比DES和DESede都快,至今还没有被破解的报道。经过验证,目前采用的AES算法能够有效抵御已知的针对DES算法的所有攻击方法,如部分差分攻击、相关秘钥攻击等。AES算法因秘钥建立时间短、灵敏性好、内存需求低等优点,在各个领域得到广泛的研究与应用。
四、非对称加密算法
非对称加密和对称加密算法相比,多了一把秘钥,为双秘钥模式,一个公开称为公钥,一个保密称为私钥。遵循公钥加密私钥解密,或者私钥加密公钥解密。非对称加密算法源于DH算法,后又有基于椭圆曲线加密算法的密钥交换算法ECDH,不过目前最为流行的非对称加密算法是RSA。
RSA (Rivest–Shamir–Adleman algorithm):
RSA 算法是是目前应用最广泛的非对称加密算法,像 SSL/TLS、SSH 等协议中就用到了 RSA 算法。
RSA算法是一种基于大数分解的困难性的非对称加密算法,它需要选择两个大素数作为私钥的一部分,然后计算出它们的乘积作为公钥的一部分(寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难)。
1. 使用公钥和私钥
1)公钥用于加密数据,确保数据机密性。
2)私钥用于解密数据,或者用于数字签名,确保数据的完整性和来源。
2. 数据交换过程
RSA算法的数据交换过程分为如下几步:
1)A 生成 RSA 密钥对(包括公钥和私钥)。
2)A 向 B 发布公钥,使得 B 能用公钥来加密数据。
3)A 使用 B 的公钥加密数据,并将加密后的数据发送给 B。
4)B 使用自己的私钥解密数据,以获取原始消息。
5)B 使用 A 的公钥加密数据,并将加密后的数据发送给 A。
6)A 使用自己的私钥解密数据,以获取原始消息。
RSA 算法的优点是简单易用,可以用于数据加密和数字签名;缺点是运算速度慢,不适合大量数据的加密。
五、应用举例
请依据加密解密技术,以及信息摘要,数字签名技术解决以下问题
设计一个安全邮件传输系统,要求如下:
该邮件以加密方式传输,邮件最大附件内容可达2GB,发送者不可抵赖,若邮件被第三方截获,第三方无法篡改。
下面是整体设计思路:
参考链接:
https://juejin.cn/post/7022798228492042276
https://javaguide.cn/system-design/security/encryption-algorithms.html