前言
AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,用于加密电子数据。它是由比利时密码学家Joan Daemen和Vincent Rijmen设计的,并于2001年由美国国家标准与技术研究院(NIST)采纳为官方标准。
一、AES加密原理
AES算法基于替换和置换操作,它支持128位、192位和256位的密钥长度,并且对于每种密钥长度,都有一个固定的加密轮数(10轮、12轮、14轮)。
初始状态:将明文分成128位的数据块,并将其放入一个4×4字节的矩阵中。
密钥扩展:从原始密钥派生出一系列子密钥,用于每一轮加密。
加密过程:包括多个相同的轮次,每轮包括四个步骤:字节替代、行移位、列混合和密钥加法。
最终轮:除了不进行列混合外,其余步骤与之前的轮相同。
1、其中不同的密钥长度解释如下:
AES加密算法支持128位、192位和256位的密钥长度,它们的主要区别在于安全性和性能:
安全性:
128位密钥:提供非常高的安全性,对于大多数应用来说已经足够安全。
192位密钥:比128位更安全一些,但在实际应用中并不常见。
256位密钥:提供最高的安全性,理论上是最难破解的。
性能:
128位密钥:由于密钥较短,加密和解密速度较快。
192位密钥:加密和解密速度略慢于128位密钥。
256位密钥:加密和解密速度最慢,但通常这种性能差异在现代硬件上是可以接受的。
加密轮数:
128位密钥:加密轮数为10轮。
192位密钥:加密轮数为12轮。
256位密钥:加密轮数为14轮。
密钥生成:
密钥长度越长,生成密钥所需的计算资源越多。
2、如何选择密钥长度
选择哪种密钥长度主要取决于您的安全需求和性能要求:
一般应用:对于大多数普通应用,128位密钥已经足够安全,同时提供了较好的性能。
高安全性需求:如果您处理的是极其敏感的数据,或者需要满足某些合规性要求,那么256位密钥可能是更好的选择。
性能敏感型应用:如果您的应用对性能极为敏感,比如需要处理大量的数据流,那么可能需要权衡安全性和性能,考虑使用128位密钥。
3、加密模式
AES加密支持多种工作模式,每种模式都有其特定的应用场景和优势。以下是AES加密的一些常见模式
1、电码本模式(ECB, Electronic Codebook)
描述:ECB是最简单的模式,它将明文分割成块,并独立地对每个块进行加密。每个块使用相同的密钥进行加密。
优点:实现简单,速度快。
缺点:相同的明文块总是产生相同的密文块,容易暴露模式。
适用场景:适用于小数据量加密,如加密单个密码或小文件。
2、密码分组链接模式(CBC, Cipher Block Chaining)
描述:CBC模式中,每个明文块在加密前与前一个密文块进行异或运算。第一个明文块与一个初始化向量(IV)进行异或。
优点:提高了安全性,相同的明文块在不同的位置会产生不同的密文块。
缺点:加密和解密过程依赖于块间的顺序,无法并行处理。
适用场景:适用于需要较高安全性的场景,如文件加密、数据库加密等。
3、计数器模式(CTR, Counter)
描述:CTR模式使用一个计数器和一个密钥生成伪随机序列,该序列与明文进行异或运算得到密文。计数器可以预先设置,使得加密过程可以并行化。
优点:可以并行处理,适合高速加密。
缺点:需要确保计数器的唯一性。
适用场景:适用于需要高速加密的应用,如网络通信、视频流传输等。
4、输出反馈模式(OFB, Output Feedback)
描述:OFB模式类似于CTR模式,但使用了密文的反馈机制。它使用密钥和一个初始向量生成伪随机序列,然后与明文进行异或运算。
优点:可以并行处理,适用于流式加密。
缺点:错误传播问题,即密文中的错误会影响后续的解密结果。
适用场景:适用于实时传输数据的加密,如音频或视频流。
5、密码反馈模式(CFB, Cipher Feedback)
描述:CFB模式使用密文的反馈机制,将密文的一部分作为输入来生成下一个密文块。
优点:可以并行处理,适用于流式加密。
缺点:错误传播问题,即密文中的错误会影响后续的解密结果。
适用场景:适用于实时传输数据的加密,如网络通信。
- 选择合适的模式
选择哪种模式取决于你的具体需求:
如果你关心的是加密速度并且数据块之间没有相关性,可以选择 ECB。
如果你需要更高的安全性,并且数据块之间存在相关性,可以选择 CBC。
如果你需要并行处理数据,可以选择 CTR。
如果你需要处理连续的数据流,并且希望减少错误传播的影响,可以选择 OFB 或 CFB。
在大多数情况下,CBC 和 CTR 是最常用的模式。如果你需要在性能和安全性之间取得平衡,CTR 模式通常是一个不错的选择,因为它既可以并行处理又提供了良好的安全性。
4、填充模式
填充(Padding)模式用于处理不足一个完整分组大小的数据块。填充模式确保所有的数据块都是固定长度的,这样就可以正确地进行加密和解密。以下是几种常见的填充模式
1、PKCS5Padding
描述:PKCS5Padding 是一种常用的填充算法,适用于所有AES加密模式,包括ECB、CBC和CTR模式。在这种模式下,最后一个数据块会被填充到16字节的倍数。填充的字节数等于16减去最后一个数据块的长度(模16)。填充字节的值等于需要添加的字节数。
示例:如果最后一个数据块长度为12字节,则填充4个值为4的字节。
2、PKCS7Padding
描述:PKCS7Padding 与PKCS5Padding非常相似,但适用于任何分组大小(最大为255字节)。填充的字节数等于分组大小减去最后一个数据块的长度(模分组大小)。填充字节的值等于需要添加的字节数。
示例:如果最后一个数据块长度为10字节,分组大小为16字节,则填充6个值为6的字节。
3、ISO10126Padding
描述:ISO10126Padding 也是一种填充算法,它在最后一个数据块的末尾填充一个随机字节序列,然后在序列的末尾添加一个字节,其值等于填充的总字节数。
示例:如果最后一个数据块长度为10字节,则先填充5个随机字节,最后添加一个值为6的字节。
4、ZeroPadding
描述:ZeroPadding 用零字节填充最后一个数据块,直到达到分组大小。
示例:如果最后一个数据块长度为10字节,则填充6个零字节。
5、NoPadding
描述:不填充,如CTR模式,不需要填充,因为它们可以处理任意长度的数据。
示例:在CTR模式下,不需要对数据进行填充。
- 选择合适的填充模式
选择填充模式时,通常会考虑以下几个因素:
安全性:PKCS5Padding 和 PKCS7Padding提供了更好的安全性,因为它们确保了填充字节的值是唯一的,并且可以通过检查填充字节来验证数据的完整性。
兼容性:PKCS5Padding 和 PKCS7Padding 是最常用的标准,因此与其他系统或库的兼容性最好。
性能:ZeroPadding 可能更快,因为它只需要填充零字节,但这可能会降低安全性。 - 注意:jdk自带的加密模块不支持PKCS7Padding 填充,如果需要PKCS7Padding 需要引入第三方支持*
二、使用案例
下面例子将使用CBC模式和PKCS5Padding填充进行AES加密和解密,大家有需要可以直接复制到自己的项目当中使用
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException