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

posted @ 2024-11-15 11:55  欢乐豆123  阅读(3)  评论(0编辑  收藏  举报